]>
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"
93 SSLEncodeCertificate(SSLRecord
*certificate
, SSLContext
*ctx
)
100 /* Match DER-encoded root certs here */
102 cert
= ctx
->localCert
;
107 { totalLength
+= 3 + cert
->derCert
.length
; /* 3 for encoded length field */
112 certificate
->contentType
= SSL_handshake
;
113 assert((ctx
->negProtocolVersion
== SSL_Version_3_0
) ||
114 (ctx
->negProtocolVersion
== TLS_Version_1_0
));
115 certificate
->protocolVersion
= ctx
->negProtocolVersion
;
116 if ((err
= SSLAllocBuffer(&certificate
->contents
, totalLength
+ 7, &ctx
->sysCtx
)) != 0)
119 progress
= certificate
->contents
.data
;
120 *progress
++ = SSL_certificate
;
121 progress
= SSLEncodeInt(progress
, totalLength
+3, 3); /* Handshake message length */
122 progress
= SSLEncodeInt(progress
, totalLength
, 3); /* Vector length */
124 /* Root cert is first in the linked list, but has to go last, so walk list backwards */
125 for (i
= 0; i
< certCount
; ++i
)
126 { cert
= ctx
->localCert
;
127 for (j
= i
+1; j
< certCount
; ++j
)
129 progress
= SSLEncodeInt(progress
, cert
->derCert
.length
, 3);
130 memcpy(progress
, cert
->derCert
.data
, cert
->derCert
.length
);
131 progress
+= cert
->derCert
.length
;
134 CASSERT(progress
== certificate
->contents
.data
+ certificate
->contents
.length
);
136 if (ctx
->protocolSide
== SSL_ClientSide
)
143 SSLProcessCertificate(SSLBuffer message
, SSLContext
*ctx
)
145 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
;
164 cert
= (SSLCertificate
*)sslMalloc(sizeof(SSLCertificate
));
168 if ((err
= SSLAllocBuffer(&cert
->derCert
, certLen
, &ctx
->sysCtx
)) != 0)
172 memcpy(cert
->derCert
.data
, p
, certLen
);
174 cert
->next
= ctx
->peerCert
; /* Insert backwards; root cert will be first in linked list */
175 ctx
->peerCert
= cert
;
176 listLen
-= 3+certLen
;
178 CASSERT(p
== message
.data
+ message
.length
&& listLen
== 0);
180 if (ctx
->peerCert
== 0)
181 return X509CertChainInvalidErr
;
183 if((err
= sslVerifyCertChain(ctx
, ctx
->peerCert
)) != 0)
186 /* Server's certificate is the last one in the chain */
187 cert
= ctx
->peerCert
;
188 while (cert
->next
!= 0)
190 /* Convert its public key to CDSA format */
191 if ((err
= sslPubKeyFromCert(ctx
,
194 &ctx
->peerPubKeyCsp
)) != 0)
201 SSLEncodeCertificateRequest(SSLRecord
*request
, SSLContext
*ctx
)
203 #if !ST_SERVER_MODE_ENABLE
205 /* cert request only happens in server mode */
206 errorLog0("SSLEncodeCertificateRequest called\n");
207 return SSLUnsupportedErr
;
212 UInt32 dnListLen
, msgLen
;
217 dn
= ctx
->acceptableDNList
;
220 { dnListLen
+= 2 + dn
->derDN
.length
;
223 msgLen
= 1 + 1 + 2 + dnListLen
;
225 request
->contentType
= SSL_handshake
;
226 assert((ctx
->negProtocolVersion
== SSL_Version_3_0
) ||
227 (ctx
->negProtocolVersion
== TLS_Version_1_0
));
228 request
->protocolVersion
= ctx
->negProtocolVersion
;
229 if ((err
= SSLAllocBuffer(&request
->contents
, msgLen
+ 4, &ctx
->sysCtx
)) != 0)
232 progress
= request
->contents
.data
;
233 *progress
++ = SSL_certificate_request
;
234 progress
= SSLEncodeInt(progress
, msgLen
, 3);
236 *progress
++ = 1; /* one cert type */
237 *progress
++ = 1; /* RSA-sign type */
238 progress
= SSLEncodeInt(progress
, dnListLen
, 2);
239 dn
= ctx
->acceptableDNList
;
241 { progress
= SSLEncodeInt(progress
, dn
->derDN
.length
, 2);
242 memcpy(progress
, dn
->derDN
.data
, dn
->derDN
.length
);
243 progress
+= dn
->derDN
.length
;
247 CASSERT(progress
== request
->contents
.data
+ request
->contents
.length
);
250 #endif /* ST_SERVER_MODE_ENABLE */
254 SSLProcessCertificateRequest(SSLBuffer message
, SSLContext
*ctx
)
256 int i
, dnListLen
, dnLen
;
257 unsigned int typeCount
;
262 /* cert request only happens in during client authentication, which
264 errorLog0("SSLProcessCertificateRequest called\n");
265 if (message
.length
< 3) {
266 errorLog0("SSLProcessCertificateRequest: length decode error 1\n");
267 return ERR(SSLProtocolErr
);
269 progress
= message
.data
;
270 typeCount
= *progress
++;
271 if (typeCount
< 1 || message
.length
< 3 + typeCount
) {
272 errorLog0("SSLProcessCertificateRequest: length decode error 2\n");
273 return ERR(SSLProtocolErr
);
275 for (i
= 0; i
< typeCount
; i
++)
276 { if (*progress
++ == 1)
277 ctx
->x509Requested
= 1;
280 dnListLen
= SSLDecodeInt(progress
, 2);
282 if (message
.length
!= 3 + typeCount
+ dnListLen
) {
283 errorLog0("SSLProcessCertificateRequest: length decode error 3\n");
284 return ERR(SSLProtocolErr
);
286 while (dnListLen
> 0)
287 { if (dnListLen
< 2) {
288 errorLog0("SSLProcessCertificateRequest: dnListLen error 1\n");
289 return ERR(SSLProtocolErr
);
291 dnLen
= SSLDecodeInt(progress
, 2);
293 if (dnListLen
< 2 + dnLen
) {
294 errorLog0("SSLProcessCertificateRequest: dnListLen error 2\n");
295 return ERR(SSLProtocolErr
);
297 if (ERR(err
= SSLAllocBuffer(&dnBuf
, sizeof(DNListElem
), &ctx
->sysCtx
)) != 0)
299 dn
= (DNListElem
*)dnBuf
.data
;
300 if (ERR(err
= SSLAllocBuffer(&dn
->derDN
, dnLen
, &ctx
->sysCtx
)) != 0)
301 { SSLFreeBuffer(&dnBuf
, &ctx
->sysCtx
);
304 memcpy(dn
->derDN
.data
, progress
, dnLen
);
306 dn
->next
= ctx
->acceptableDNList
;
307 ctx
->acceptableDNList
= dn
;
308 dnListLen
-= 2 + dnLen
;
311 CASSERT(progress
== message
.data
+ message
.length
);
317 SSLEncodeCertificateVerify(SSLRecord
*certVerify
, SSLContext
*ctx
)
319 UInt8 signedHashData
[36];
320 SSLBuffer hashData
, shaMsgState
, md5MsgState
;
324 certVerify
->contents
.data
= 0;
325 hashData
.data
= signedHashData
;
326 hashData
.length
= 36;
328 if (ERR(err
= CloneHashState(&SSLHashSHA1
, ctx
->shaState
, &shaMsgState
, ctx
)) != 0)
330 if (ERR(err
= CloneHashState(&SSLHashMD5
, ctx
->md5State
, &md5MsgState
, ctx
)) != 0)
332 assert(ctx
->sslTslCalls
!= NULL
);
333 if (ERR(err
= ctx
->sslTslCalls
->computeCertVfyMac(ctx
,
334 hashData
, shaMsgState
, md5MsgState
)) != 0)
337 CASSERT(ctx
->signingPrivKey
!= NULL
);
338 len
= sslKeyLengthInBytes(ctx
->signingPrivKey
);
340 certVerify
->contentType
= SSL_handshake
;
341 assert((ctx
->negProtocolVersion
== SSL_Version_3_0
) ||
342 (ctx
->negProtocolVersion
== TLS_Version_1_0
));
343 certVerify
->protocolVersion
= ctx
->negProtocolVersion
;
344 if (ERR(err
= SSLAllocBuffer(&certVerify
->contents
, len
+ 6, &ctx
->sysCtx
)) != 0)
347 certVerify
->contents
.data
[0] = SSL_certificate_verify
;
348 SSLEncodeInt(certVerify
->contents
.data
+1, len
+2, 3);
349 SSLEncodeInt(certVerify
->contents
.data
+4, len
, 2);
351 err
= sslRsaRawSign(ctx
,
355 36, // MD5 size + SHA1 size
356 certVerify
->contents
.data
+6,
357 len
, // we mallocd len+6
363 CASSERT(outputLen
== len
);
368 ERR(SSLFreeBuffer(&shaMsgState
, &ctx
->sysCtx
));
369 ERR(SSLFreeBuffer(&md5MsgState
, &ctx
->sysCtx
));
375 SSLProcessCertificateVerify(SSLBuffer message
, SSLContext
*ctx
)
377 UInt8 signedHashData
[36];
379 SSLBuffer hashData
, shaMsgState
, md5MsgState
, outputData
;
380 unsigned int publicModulusLen
;
382 shaMsgState
.data
= 0;
383 md5MsgState
.data
= 0;
386 if (message
.length
< 2) {
387 errorLog0("SSLProcessCertificateVerify: msg len error\n");
388 return ERR(SSLProtocolErr
);
391 signatureLen
= (UInt16
)SSLDecodeInt(message
.data
, 2);
392 if (message
.length
!= 2 + signatureLen
) {
393 errorLog0("SSLProcessCertificateVerify: sig len error 1\n");
394 return ERR(SSLProtocolErr
);
397 CASSERT(ctx
->peerPubKey
!= NULL
);
398 publicModulusLen
= sslKeyLengthInBytes(ctx
->peerPubKey
);
400 if (signatureLen
!= publicModulusLen
) {
401 errorLog0("SSLProcessCertificateVerify: sig len error 2\n");
402 return ERR(SSLProtocolErr
);
405 hashData
.data
= signedHashData
;
406 hashData
.length
= 36;
408 if (ERR(err
= CloneHashState(&SSLHashSHA1
, ctx
->shaState
, &shaMsgState
, ctx
)) != 0)
410 if (ERR(err
= CloneHashState(&SSLHashMD5
, ctx
->md5State
, &md5MsgState
, ctx
)) != 0)
412 assert(ctx
->sslTslCalls
!= NULL
);
413 if (ERR(err
= ctx
->sslTslCalls
->computeCertVfyMac(ctx
, hashData
,
414 shaMsgState
, md5MsgState
)) != 0)
417 if (ERR(err
= SSLAllocBuffer(&outputData
, publicModulusLen
, &ctx
->sysCtx
)) != 0)
421 * The CSP does the decrypt & compare for us in one shot
423 err
= sslRsaRawVerify(ctx
,
425 ctx
->peerPubKeyCsp
, // FIXME - maybe we just use cspHand?
436 ERR(SSLFreeBuffer(&shaMsgState
, &ctx
->sysCtx
));
437 ERR(SSLFreeBuffer(&md5MsgState
, &ctx
->sysCtx
));
438 ERR(SSLFreeBuffer(&outputData
, &ctx
->sysCtx
));