]>
git.saurik.com Git - apple/security.git/blob - SecureTransport/hdskcert.c
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
22 Contains: certificate request/verify messages
24 Written by: Doug Mitchell, based on Netscape SSLRef 3.0
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
29 /* *********************************************************************
32 SSLRef 3.0 Final -- 11/19/96
34 Copyright (c)1996 by Netscape Communications Corp.
36 By retrieving this software you are bound by the licensing terms
37 disclosed in the file "LICENSE.txt". Please read it, and if you don't
38 accept the terms, delete this software.
40 SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
41 View, California <http://home.netscape.com/> and Consensus Development
42 Corporation of Berkeley, California <http://www.consensus.com/>.
44 *********************************************************************
46 File: hdskcert.c Contains support for certificate-related messages
48 Support for encoding and decoding the certificate, certificate
49 request, and certificate verify messages.
51 ****************************************************************** */
81 #ifndef _APPLE_CDSA_H_
82 #include "appleCdsa.h"
92 SSLEncodeCertificate(SSLRecord
*certificate
, SSLContext
*ctx
)
99 /* Match DER-encoded root certs here */
101 cert
= ctx
->localCert
;
106 { totalLength
+= 3 + cert
->derCert
.length
; /* 3 for encoded length field */
111 certificate
->contentType
= SSL_handshake
;
112 certificate
->protocolVersion
= SSL_Version_3_0
;
113 if ((err
= SSLAllocBuffer(&certificate
->contents
, totalLength
+ 7, &ctx
->sysCtx
)) != 0)
116 progress
= certificate
->contents
.data
;
117 *progress
++ = SSL_certificate
;
118 progress
= SSLEncodeInt(progress
, totalLength
+3, 3); /* Handshake message length */
119 progress
= SSLEncodeInt(progress
, totalLength
, 3); /* Vector length */
121 /* Root cert is first in the linked list, but has to go last, so walk list backwards */
122 for (i
= 0; i
< certCount
; ++i
)
123 { cert
= ctx
->localCert
;
124 for (j
= i
+1; j
< certCount
; ++j
)
126 progress
= SSLEncodeInt(progress
, cert
->derCert
.length
, 3);
127 memcpy(progress
, cert
->derCert
.data
, cert
->derCert
.length
);
128 progress
+= cert
->derCert
.length
;
131 CASSERT(progress
== certificate
->contents
.data
+ certificate
->contents
.length
);
133 if (ctx
->protocolSide
== SSL_ClientSide
)
140 SSLProcessCertificate(SSLBuffer message
, SSLContext
*ctx
)
142 UInt32 listLen
, certLen
;
147 SSLCertificate
*cert
;
150 listLen
= SSLDecodeInt(p
,3);
152 if (listLen
+ 3 != message
.length
) {
153 errorLog0("SSLProcessCertificate: length decode error 1\n");
154 return SSLProtocolErr
;
158 { certLen
= SSLDecodeInt(p
,3);
160 if (listLen
< certLen
+ 3) {
161 errorLog0("SSLProcessCertificate: length decode error 2\n");
162 return SSLProtocolErr
;
165 cert
= (SSLCertificate
*)sslMalloc(sizeof(SSLCertificate
));
169 if ((err
= SSLAllocBuffer(&cert
->derCert
, certLen
, &ctx
->sysCtx
)) != 0)
174 if ((err
= SSLAllocBuffer(&buf
, sizeof(SSLCertificate
), &ctx
->sysCtx
)) != 0)
176 cert
= (SSLCertificate
*)buf
.data
;
177 if ((err
= SSLAllocBuffer(&cert
->derCert
, certLen
, &ctx
->sysCtx
)) != 0)
178 { SSLFreeBuffer(&buf
, &ctx
->sysCtx
);
182 memcpy(cert
->derCert
.data
, p
, certLen
);
184 cert
->next
= ctx
->peerCert
; /* Insert backwards; root cert will be first in linked list */
185 ctx
->peerCert
= cert
;
187 /* we don't parse this, the CL does */
188 if ((err
= ASNParseX509Certificate(cert
->derCert
, &cert
->cert
, ctx
)) != 0)
191 listLen
-= 3+certLen
;
193 CASSERT(p
== message
.data
+ message
.length
&& listLen
== 0);
195 if (ctx
->peerCert
== 0)
196 return X509CertChainInvalidErr
;
199 if((err
= sslVerifyCertChain(ctx
, ctx
->peerCert
)) != 0)
201 if ((err
= X509VerifyCertChain(ctx
->peerCert
, ctx
)) != 0)
205 /* Server's certificate is the last one in the chain */
206 cert
= ctx
->peerCert
;
207 while (cert
->next
!= 0)
209 /* Convert its public key to RSAREF format */
211 if ((err
= sslPubKeyFromCert(ctx
,
214 &ctx
->peerPubKeyCsp
)) != 0)
216 if ((err
= X509ExtractPublicKey(&cert
->cert
.pubKey
, &ctx
->peerKey
)) != 0)
222 * This appears to be redundant with the cert check above;
223 * it's here for additional cert checking by clients of SSLRef.
225 if (ctx
->certCtx
.checkCertFunc
!= 0)
226 { SSLBuffer certList
, *certs
;
230 if ((err
= SSLGetPeerCertificateChainLength(ctx
, &certCount
)) != 0)
232 if ((err
= SSLAllocBuffer(&certList
, certCount
* sizeof(SSLBuffer
), &ctx
->sysCtx
)) != 0)
234 certs
= (SSLBuffer
*)certList
.data
;
236 for (i
= 0; i
< certCount
; i
++, c
= c
->next
)
237 certs
[i
] = c
->derCert
;
239 if ((err
= ctx
->certCtx
.checkCertFunc(certCount
, certs
, ctx
->certCtx
.checkCertRef
)) != 0)
240 { SSLFreeBuffer(&certList
, &ctx
->sysCtx
);
243 SSLFreeBuffer(&certList
, &ctx
->sysCtx
);
245 #endif /* _APPLE_CDSA_ */
251 SSLEncodeCertificateRequest(SSLRecord
*request
, SSLContext
*ctx
)
253 #if !ST_SERVER_MODE_ENABLE
255 /* cert request only happens in server mode */
256 errorLog0("SSLEncodeCertificateRequest called\n");
257 return SSLUnsupportedErr
;
262 UInt32 dnListLen
, msgLen
;
267 dn
= ctx
->acceptableDNList
;
270 { dnListLen
+= 2 + dn
->derDN
.length
;
273 msgLen
= 1 + 1 + 2 + dnListLen
;
275 request
->contentType
= SSL_handshake
;
276 request
->protocolVersion
= SSL_Version_3_0
;
277 if ((err
= SSLAllocBuffer(&request
->contents
, msgLen
+ 4, &ctx
->sysCtx
)) != 0)
280 progress
= request
->contents
.data
;
281 *progress
++ = SSL_certificate_request
;
282 progress
= SSLEncodeInt(progress
, msgLen
, 3);
284 *progress
++ = 1; /* one cert type */
285 *progress
++ = 1; /* RSA-sign type */
286 progress
= SSLEncodeInt(progress
, dnListLen
, 2);
287 dn
= ctx
->acceptableDNList
;
289 { progress
= SSLEncodeInt(progress
, dn
->derDN
.length
, 2);
290 memcpy(progress
, dn
->derDN
.data
, dn
->derDN
.length
);
291 progress
+= dn
->derDN
.length
;
295 CASSERT(progress
== request
->contents
.data
+ request
->contents
.length
);
298 #endif /* ST_SERVER_MODE_ENABLE */
302 SSLProcessCertificateRequest(SSLBuffer message
, SSLContext
*ctx
)
304 int i
, dnListLen
, dnLen
;
305 unsigned int typeCount
;
310 /* cert request only happens in during client authentication, which
312 errorLog0("SSLProcessCertificateRequest called\n");
313 if (message
.length
< 3) {
314 errorLog0("SSLProcessCertificateRequest: length decode error 1\n");
315 return ERR(SSLProtocolErr
);
317 progress
= message
.data
;
318 typeCount
= *progress
++;
319 if (typeCount
< 1 || message
.length
< 3 + typeCount
) {
320 errorLog0("SSLProcessCertificateRequest: length decode error 2\n");
321 return ERR(SSLProtocolErr
);
323 for (i
= 0; i
< typeCount
; i
++)
324 { if (*progress
++ == 1)
325 ctx
->x509Requested
= 1;
328 dnListLen
= SSLDecodeInt(progress
, 2);
330 if (message
.length
!= 3 + typeCount
+ dnListLen
) {
331 errorLog0("SSLProcessCertificateRequest: length decode error 3\n");
332 return ERR(SSLProtocolErr
);
334 while (dnListLen
> 0)
335 { if (dnListLen
< 2) {
336 errorLog0("SSLProcessCertificateRequest: dnListLen error 1\n");
337 return ERR(SSLProtocolErr
);
339 dnLen
= SSLDecodeInt(progress
, 2);
341 if (dnListLen
< 2 + dnLen
) {
342 errorLog0("SSLProcessCertificateRequest: dnListLen error 2\n");
343 return ERR(SSLProtocolErr
);
345 if (ERR(err
= SSLAllocBuffer(&dnBuf
, sizeof(DNListElem
), &ctx
->sysCtx
)) != 0)
347 dn
= (DNListElem
*)dnBuf
.data
;
348 if (ERR(err
= SSLAllocBuffer(&dn
->derDN
, dnLen
, &ctx
->sysCtx
)) != 0)
349 { SSLFreeBuffer(&dnBuf
, &ctx
->sysCtx
);
352 memcpy(dn
->derDN
.data
, progress
, dnLen
);
354 dn
->next
= ctx
->acceptableDNList
;
355 ctx
->acceptableDNList
= dn
;
356 dnListLen
-= 2 + dnLen
;
359 CASSERT(progress
== message
.data
+ message
.length
);
365 SSLEncodeCertificateVerify(SSLRecord
*certVerify
, SSLContext
*ctx
)
367 UInt8 signedHashData
[36];
368 SSLBuffer hashData
, shaMsgState
, md5MsgState
;
372 certVerify
->contents
.data
= 0;
373 hashData
.data
= signedHashData
;
374 hashData
.length
= 36;
376 if (ERR(err
= CloneHashState(&SSLHashSHA1
, ctx
->shaState
, &shaMsgState
, ctx
)) != 0)
378 if (ERR(err
= CloneHashState(&SSLHashMD5
, ctx
->md5State
, &md5MsgState
, ctx
)) != 0)
380 if (ERR(err
= SSLCalculateFinishedMessage(hashData
, shaMsgState
, md5MsgState
, 0, ctx
)) != 0)
384 len
= (ctx
->localKey
.bits
+ 7)/8;
386 { A_RSA_KEY
*keyInfo
;
389 if ((rsaResult
= B_GetKeyInfo((POINTER
*)&keyInfo
, ctx
->localKey
, KI_RSAPublic
)) != 0)
390 return ERR(SSLUnknownErr
);
391 len
= keyInfo
->modulus
.len
;
394 CASSERT(ctx
->signingPrivKey
!= NULL
);
395 len
= sslKeyLengthInBytes(ctx
->signingPrivKey
);
397 #error No asymmetric crypto specified
398 #endif /* RSAREF / BSAFE */
400 certVerify
->contentType
= SSL_handshake
;
401 certVerify
->protocolVersion
= SSL_Version_3_0
;
402 if (ERR(err
= SSLAllocBuffer(&certVerify
->contents
, len
+ 6, &ctx
->sysCtx
)) != 0)
405 certVerify
->contents
.data
[0] = SSL_certificate_verify
;
406 SSLEncodeInt(certVerify
->contents
.data
+1, len
+2, 3);
407 SSLEncodeInt(certVerify
->contents
.data
+4, len
, 2);
409 if (RSAPrivateEncrypt(certVerify
->contents
.data
+6, &outputLen
,
410 signedHashData
, 36, &ctx
->localKey
) != 0) /* Sign the structure */
411 { err
= ERR(SSLUnknownErr
);
415 { B_ALGORITHM_OBJ rsa
;
416 B_ALGORITHM_METHOD
*chooser
[] = { &AM_RSA_CRT_ENCRYPT
, 0 };
419 if (ERR(rsaResult
= B_CreateAlgorithmObject(&rsa
)) != 0)
420 return SSLUnknownErr
;
421 if (ERR(rsaResult
= B_SetAlgorithmInfo(rsa
, AI_PKCS_RSAPrivate
, 0)) != 0)
422 return SSLUnknownErr
;
423 if (ERR(rsaResult
= B_EncryptInit(rsa
, ctx
->localKey
, chooser
, NO_SURR
)) != 0)
424 return SSLUnknownErr
;
425 if (ERR(rsaResult
= B_EncryptUpdate(rsa
, certVerify
->contents
.data
+6,
426 &outputLen
, len
, signedHashData
, 36, 0, NO_SURR
)) != 0)
427 return SSLUnknownErr
;
428 if (ERR(rsaResult
= B_EncryptFinal(rsa
, certVerify
->contents
.data
+6+outputLen
,
429 &outputLen
, len
-outputLen
, 0, NO_SURR
)) != 0)
430 return SSLUnknownErr
;
431 B_DestroyAlgorithmObject(&rsa
);
435 err
= sslRsaRawSign(ctx
,
439 36, // MD5 size + SHA1 size
440 certVerify
->contents
.data
+6,
441 len
, // we mallocd len+6
447 #error No asymmetric crypto specified
448 #endif /* RSAREF / BSAFE */
450 CASSERT(outputLen
== len
);
455 ERR(SSLFreeBuffer(&shaMsgState
, &ctx
->sysCtx
));
456 ERR(SSLFreeBuffer(&md5MsgState
, &ctx
->sysCtx
));
462 SSLProcessCertificateVerify(SSLBuffer message
, SSLContext
*ctx
)
464 UInt8 signedHashData
[36];
466 SSLBuffer hashData
, shaMsgState
, md5MsgState
, outputData
;
467 #if defined(BSAFE) || defined(RSAREF)
468 unsigned int outputLen
;
470 unsigned int publicModulusLen
;
472 shaMsgState
.data
= 0;
473 md5MsgState
.data
= 0;
476 if (message
.length
< 2) {
477 errorLog0("SSLProcessCertificateVerify: msg len error\n");
478 return ERR(SSLProtocolErr
);
481 signatureLen
= (UInt16
)SSLDecodeInt(message
.data
, 2);
482 if (message
.length
!= 2 + signatureLen
) {
483 errorLog0("SSLProcessCertificateVerify: sig len error 1\n");
484 return ERR(SSLProtocolErr
);
488 publicModulusLen
= (ctx
->peerKey
.bits
+ 7)/8;
490 { A_RSA_KEY
*keyInfo
;
493 if ((rsaResult
= B_GetKeyInfo((POINTER
*)&keyInfo
, ctx
->peerKey
, KI_RSAPublic
)) != 0)
494 return SSLUnknownErr
;
495 publicModulusLen
= keyInfo
->modulus
.len
;
498 CASSERT(ctx
->peerPubKey
!= NULL
);
499 publicModulusLen
= sslKeyLengthInBytes(ctx
->peerPubKey
);
501 #error No asymmetric crypto specified
502 #endif /* RSAREF / BSAFE */
504 if (signatureLen
!= publicModulusLen
) {
505 errorLog0("SSLProcessCertificateVerify: sig len error 2\n");
506 return ERR(SSLProtocolErr
);
509 hashData
.data
= signedHashData
;
510 hashData
.length
= 36;
512 if (ERR(err
= CloneHashState(&SSLHashSHA1
, ctx
->shaState
, &shaMsgState
, ctx
)) != 0)
514 if (ERR(err
= CloneHashState(&SSLHashMD5
, ctx
->md5State
, &md5MsgState
, ctx
)) != 0)
516 if (ERR(err
= SSLCalculateFinishedMessage(hashData
, shaMsgState
, md5MsgState
, 0, ctx
)) != 0)
519 if (ERR(err
= SSLAllocBuffer(&outputData
, publicModulusLen
, &ctx
->sysCtx
)) != 0)
523 if (RSAPublicDecrypt(outputData
.data
, &outputLen
,
524 message
.data
+ 2, signatureLen
, &ctx
->peerKey
) != 0)
525 { ERR(err
= SSLUnknownErr
);
529 { B_ALGORITHM_OBJ rsa
;
530 B_ALGORITHM_METHOD
*chooser
[] = { &AM_MD2
, &AM_MD5
, &AM_RSA_DECRYPT
, 0 };
532 unsigned int decryptLen
;
534 if ((rsaResult
= B_CreateAlgorithmObject(&rsa
)) != 0)
535 return SSLUnknownErr
;
536 if ((rsaResult
= B_SetAlgorithmInfo(rsa
, AI_PKCS_RSAPublic
, 0)) != 0)
537 return SSLUnknownErr
;
538 if ((rsaResult
= B_DecryptInit(rsa
, ctx
->peerKey
, chooser
, NO_SURR
)) != 0)
539 return SSLUnknownErr
;
540 if ((rsaResult
= B_DecryptUpdate(rsa
, outputData
.data
, &decryptLen
, 36,
541 message
.data
+ 2, signatureLen
, 0, NO_SURR
)) != 0)
542 return SSLUnknownErr
;
543 outputLen
= decryptLen
;
544 if ((rsaResult
= B_DecryptFinal(rsa
, outputData
.data
+outputLen
,
545 &decryptLen
, 36-outputLen
, 0, NO_SURR
)) != 0)
546 return SSLUnknownErr
;
547 outputLen
+= decryptLen
;
548 B_DestroyAlgorithmObject(&rsa
);
552 * The CSP does the decrypt & compare for us in one shot
554 err
= sslRsaRawVerify(ctx
,
556 ctx
->peerPubKeyCsp
, // FIXME - maybe we just use cspHand?
565 #endif /* RSAREF / BSAFE */
568 /* we don't have to do the compare */
571 ERR(err
= SSLProtocolErr
);
574 outputData
.length
= outputLen
;
576 DUMP_BUFFER_NAME("Finished got ", outputData
);
577 DUMP_BUFFER_NAME("Finished wanted", hashData
);
579 if (memcmp(outputData
.data
, signedHashData
, 36) != 0)
581 ERR(err
= SSLProtocolErr
);
584 #endif /* BSAFE, RSAREF only */
589 ERR(SSLFreeBuffer(&shaMsgState
, &ctx
->sysCtx
));
590 ERR(SSLFreeBuffer(&md5MsgState
, &ctx
->sysCtx
));
591 ERR(SSLFreeBuffer(&outputData
, &ctx
->sysCtx
));