]> git.saurik.com Git - apple/security.git/blob - libsecurity_ssl/lib/sslCert.c
Security-55178.0.1.tar.gz
[apple/security.git] / libsecurity_ssl / lib / sslCert.c
1 /*
2 * Copyright (c) 1999-2001,2005-2012 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * sslCert.c - certificate request/verify messages
26 */
27
28 #include "ssl.h"
29 #include "sslContext.h"
30 #include "sslHandshake.h"
31 #include "sslMemory.h"
32 #include "sslAlertMessage.h"
33 #include "sslDebug.h"
34 #include "sslUtils.h"
35 #include "sslDigests.h"
36 #include "sslCrypto.h"
37
38 #include <string.h>
39 #include <assert.h>
40 #include <CoreFoundation/CoreFoundation.h>
41 #include <Security/SecCertificate.h>
42 #include <Security/SecCertificatePriv.h>
43 #include <Security/SecInternal.h>
44 #include <Security/oidsalg.h>
45
46
47 OSStatus
48 SSLEncodeCertificate(SSLRecord *certificate, SSLContext *ctx)
49 { OSStatus err;
50 size_t totalLength;
51 UInt8 *charPtr;
52 CFIndex i, certCount;
53 #ifdef USE_SSLCERTIFICATE
54 int j;
55 SSLCertificate *cert;
56 #else
57 CFArrayRef certChain;
58 #endif
59 int head;
60
61 /*
62 * TBD: for client side, match Match DER-encoded acceptable DN list
63 * (ctx->acceptableDNList) to one of our certs. For now we just send
64 * what we have since we don't support multiple certs.
65 *
66 * Note this can be called with localCert==0 for client side in TLS1+ and DTLS;
67 * in that case we send an empty cert msg.
68 */
69 assert(ctx->negProtocolVersion >= SSL_Version_3_0);
70 assert((ctx->localCert != NULL) || (ctx->negProtocolVersion >= TLS_Version_1_0));
71 totalLength = 0;
72
73 #ifdef USE_SSLCERTIFICATE
74 certCount = 0;
75 cert = ctx->localCert;
76 while (cert)
77 { totalLength += 3 + cert->derCert.length; /* 3 for encoded length field */
78 ++certCount;
79 cert = cert->next;
80 }
81 #else
82 certChain = ctx->localCert;
83 certCount = certChain ? CFArrayGetCount(certChain) : 0;
84 for (i = 0; i < certCount; ++i) {
85 SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certChain, i);
86 totalLength += 3 + SecCertificateGetLength(cert); /* 3 for encoded length field */
87 }
88 #endif
89 certificate->contentType = SSL_RecordTypeHandshake;
90 certificate->protocolVersion = ctx->negProtocolVersion;
91 head = SSLHandshakeHeaderSize(certificate);
92 if ((err = SSLAllocBuffer(&certificate->contents, totalLength + head + 3, ctx)) != 0)
93 return err;
94
95 charPtr = SSLEncodeHandshakeHeader(ctx, certificate, SSL_HdskCert, totalLength+3);
96
97 charPtr = SSLEncodeSize(charPtr, totalLength, 3); /* Vector length */
98
99 #ifdef USE_SSLCERTIFICATE
100 /* Root cert is first in the linked list, but has to go last,
101 * so walk list backwards */
102 for (i = 0; i < certCount; ++i)
103 { cert = ctx->localCert;
104 for (j = i+1; j < certCount; ++j)
105 cert = cert->next;
106 charPtr = SSLEncodeSize(charPtr, cert->derCert.length, 3);
107 memcpy(charPtr, cert->derCert.data, cert->derCert.length);
108 charPtr += cert->derCert.length;
109 }
110 #else
111 /* Root cert is last in the array, and has to go last,
112 * so walk list forwards */
113 for (i = 0; i < certCount; ++i) {
114 SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certChain, i);
115 CFIndex certLength = SecCertificateGetLength(cert);
116 charPtr = SSLEncodeSize(charPtr, certLength, 3);
117 memcpy(charPtr, SecCertificateGetBytePtr(cert), certLength);
118 charPtr += certLength;
119 }
120 #endif
121
122 assert(charPtr == certificate->contents.data + certificate->contents.length);
123
124 if ((ctx->protocolSide == kSSLClientSide) && (ctx->localCert)) {
125 /* this tells us to send a CertificateVerify msg after the
126 * client key exchange. We skip the cert vfy if we just
127 * sent an empty cert msg (i.e., we were asked for a cert
128 * but we don't have one). */
129 ctx->certSent = 1;
130 assert(ctx->clientCertState == kSSLClientCertRequested);
131 assert(ctx->certRequested);
132 ctx->clientCertState = kSSLClientCertSent;
133 }
134 if(certCount == 0) {
135 sslCertDebug("...sending empty cert msg");
136 }
137 return noErr;
138 }
139
140 OSStatus
141 SSLProcessCertificate(SSLBuffer message, SSLContext *ctx)
142 {
143 size_t listLen, certLen;
144 UInt8 *p;
145 OSStatus err;
146 #ifdef USE_SSLCERTIFICATE
147 SSLCertificate *cert;
148 #else
149 CFMutableArrayRef certChain = NULL;
150 SecCertificateRef cert;
151 #endif
152
153 p = message.data;
154 listLen = SSLDecodeInt(p,3);
155 p += 3;
156 if (listLen + 3 != message.length) {
157 sslErrorLog("SSLProcessCertificate: length decode error 1\n");
158 return errSSLProtocol;
159 }
160
161 while (listLen > 0)
162 { certLen = SSLDecodeInt(p,3);
163 p += 3;
164 if (listLen < certLen + 3) {
165 sslErrorLog("SSLProcessCertificate: length decode error 2\n");
166 return errSSLProtocol;
167 }
168 #ifdef USE_SSLCERTIFICATE
169 cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
170 if(cert == NULL) {
171 return memFullErr;
172 }
173 if ((err = SSLAllocBuffer(&cert->derCert, certLen, ctx)) != 0)
174 { sslFree(cert);
175 return err;
176 }
177 memcpy(cert->derCert.data, p, certLen);
178 p += certLen;
179 cert->next = ctx->peerCert; /* Insert backwards; root cert
180 * will be first in linked list */
181 ctx->peerCert = cert;
182 #else
183 if (!certChain) {
184 certChain = CFArrayCreateMutable(kCFAllocatorDefault, 0,
185 &kCFTypeArrayCallBacks);
186 if (certChain == NULL) {
187 return memFullErr;
188 }
189 if (ctx->peerCert) {
190 sslDebugLog("SSLProcessCertificate: releasing existing cert chain\n");
191 CFRelease(ctx->peerCert);
192 }
193 ctx->peerCert = certChain;
194 }
195 cert = SecCertificateCreateWithBytes(NULL, p, certLen);
196 #if SSL_DEBUG
197 {
198 /* print cert name when debugging; leave disabled otherwise */
199 CFStringRef certName = NULL;
200 OSStatus status = SecCertificateInferLabel(cert, &certName);
201 char buf[1024];
202 if (!certName || !CFStringGetCString(certName, buf, 1024-1, kCFStringEncodingUTF8)) { buf[0]=0; }
203 sslDebugLog("SSLProcessCertificate: received \"%s\" (%ld bytes)\n", buf, certLen);
204 CFReleaseSafe(certName);
205 }
206 #endif
207 if (cert == NULL) {
208 sslErrorLog("SSLProcessCertificate: unable to create cert ref from data\n");
209 return memFullErr;
210 }
211 p += certLen;
212 /* Insert forwards; root cert will be last in linked list */
213 CFArrayAppendValue(certChain, cert);
214 CFRelease(cert);
215 #endif
216 listLen -= 3+certLen;
217 }
218 assert(p == message.data + message.length && listLen == 0);
219
220 if (!ctx->peerCert) {
221 /* this *might* be OK... */
222 if((ctx->protocolSide == kSSLServerSide) &&
223 (ctx->clientAuth != kAlwaysAuthenticate)) {
224 /*
225 * we tried to authenticate, client doesn't have a cert, and
226 * app doesn't require it. OK.
227 */
228 return noErr;
229 }
230 else {
231 AlertDescription desc;
232 if(ctx->negProtocolVersion == SSL_Version_3_0) {
233 /* this one's for SSL3 only */
234 desc = SSL_AlertBadCert;
235 }
236 else {
237 desc = SSL_AlertCertUnknown;
238 }
239 SSLFatalSessionAlert(desc, ctx);
240 return errSSLXCertChainInvalid;
241 }
242 }
243
244 if((err = sslVerifyCertChain(ctx, ctx->peerCert, true)) != 0) {
245 AlertDescription desc;
246 switch(err) {
247 case errSSLUnknownRootCert:
248 case errSSLNoRootCert:
249 desc = SSL_AlertUnknownCA;
250 break;
251 case errSSLCertExpired:
252 case errSSLCertNotYetValid:
253 desc = SSL_AlertCertExpired;
254 break;
255 case errSSLXCertChainInvalid:
256 default:
257 desc = SSL_AlertCertUnknown;
258 break;
259 }
260 SSLFatalSessionAlert(desc, ctx);
261 }
262
263 if (err == noErr) {
264 if(ctx->peerPubKey != NULL) {
265 /* renegotiating - free old key first */
266 sslFreePubKey(&ctx->peerPubKey);
267 }
268 err = sslCopyPeerPubKey(ctx, &ctx->peerPubKey);
269 }
270
271 /* Now that cert verification is done, update context state */
272 /* (this code was formerly in SSLProcessHandshakeMessage, */
273 /* directly after the return from SSLProcessCertificate) */
274 if(ctx->protocolSide == kSSLServerSide) {
275 if(err) {
276 /*
277 * Error could be from no cert (when we require one)
278 * or invalid cert
279 */
280 if(ctx->peerCert != NULL) {
281 ctx->clientCertState = kSSLClientCertRejected;
282 }
283 } else if(ctx->peerCert != NULL) {
284 /*
285 * This still might change if cert verify msg
286 * fails. Note we avoid going to state
287 * if we get en empty cert message which is
288 * otherwise valid.
289 */
290 ctx->clientCertState = kSSLClientCertSent;
291 }
292
293 /*
294 * Schedule return to the caller to verify the client's identity.
295 * Note that an error during processing will cause early
296 * termination of the handshake.
297 */
298 if (ctx->breakOnClientAuth) {
299 ctx->signalClientAuth = true;
300 }
301 } else {
302 /*
303 * Schedule return to the caller to verify the server's identity.
304 * Note that an error during processing will cause early
305 * termination of the handshake.
306 */
307 if (ctx->breakOnServerAuth) {
308 ctx->signalServerAuth = true;
309 }
310 }
311
312 return err;
313 }
314
315 OSStatus
316 SSLEncodeCertificateRequest(SSLRecord *request, SSLContext *ctx)
317 {
318 OSStatus err;
319 size_t shListLen = 0, dnListLen, msgLen;
320 UInt8 *charPtr;
321 DNListElem *dn;
322 int head;
323
324 assert(ctx->protocolSide == kSSLServerSide);
325 if (sslVersionIsLikeTls12(ctx)) {
326 shListLen = 2 + 2 * (ctx->ecdsaEnable ? 5 : 3); //FIXME: 5:3 should not be hardcoded here.
327 }
328
329 dnListLen = 0;
330 dn = ctx->acceptableDNList;
331 while (dn)
332 { dnListLen += 2 + dn->derDN.length;
333 dn = dn->next;
334 }
335 msgLen = 1 + // number of cert types
336 2 + // cert types
337 shListLen + // SignatureAlgorithms
338 2 + // length of DN list
339 dnListLen;
340
341 request->contentType = SSL_RecordTypeHandshake;
342 assert(ctx->negProtocolVersion >= SSL_Version_3_0);
343
344 request->protocolVersion = ctx->negProtocolVersion;
345 head = SSLHandshakeHeaderSize(request);
346 if ((err = SSLAllocBuffer(&request->contents, msgLen + head, ctx)) != 0)
347 return err;
348
349 charPtr = SSLEncodeHandshakeHeader(ctx, request, SSL_HdskCertRequest, msgLen);
350
351 *charPtr++ = 2; /* two cert types */
352 *charPtr++ = SSLClientAuth_RSASign;
353 *charPtr++ = SSLClientAuth_ECDSASign;
354
355 if (shListLen) {
356 /* Encode the supported_signature_algorithms added in TLS1.2 */
357 /* We dont support SHA512 or SHA224 because we didnot implement the digest abstraction for those
358 and we dont keep a running hash for those.
359 We dont support SHA384/ECDSA because corecrypto ec does not support it with 256 bits curves */
360 charPtr = SSLEncodeSize(charPtr, shListLen - 2, 2);
361 // *charPtr++ = SSL_HashAlgorithmSHA512;
362 // *charPtr++ = SSL_SignatureAlgorithmRSA;
363 *charPtr++ = SSL_HashAlgorithmSHA384;
364 *charPtr++ = SSL_SignatureAlgorithmRSA;
365 *charPtr++ = SSL_HashAlgorithmSHA256;
366 *charPtr++ = SSL_SignatureAlgorithmRSA;
367 // *charPtr++ = SSL_HashAlgorithmSHA224;
368 // *charPtr++ = SSL_SignatureAlgorithmRSA;
369 *charPtr++ = SSL_HashAlgorithmSHA1;
370 *charPtr++ = SSL_SignatureAlgorithmRSA;
371 if (ctx->ecdsaEnable) {
372 // *charPtr++ = SSL_HashAlgorithmSHA512;
373 // *charPtr++ = SSL_SignatureAlgorithmECDSA;
374 // *charPtr++ = SSL_HashAlgorithmSHA384;
375 // *charPtr++ = SSL_SignatureAlgorithmECDSA;
376 *charPtr++ = SSL_HashAlgorithmSHA256;
377 *charPtr++ = SSL_SignatureAlgorithmECDSA;
378 // *charPtr++ = SSL_HashAlgorithmSHA224;
379 // *charPtr++ = SSL_SignatureAlgorithmECDSA;
380 *charPtr++ = SSL_HashAlgorithmSHA1;
381 *charPtr++ = SSL_SignatureAlgorithmECDSA;
382 }
383 }
384
385 charPtr = SSLEncodeSize(charPtr, dnListLen, 2);
386 dn = ctx->acceptableDNList;
387 while (dn)
388 { charPtr = SSLEncodeSize(charPtr, dn->derDN.length, 2);
389 memcpy(charPtr, dn->derDN.data, dn->derDN.length);
390 charPtr += dn->derDN.length;
391 dn = dn->next;
392 }
393
394 assert(charPtr == request->contents.data + request->contents.length);
395 return noErr;
396 }
397
398 #define SSL_ENABLE_ECDSA_SIGN_AUTH 0
399 #define SSL_ENABLE_RSA_FIXED_ECDH_AUTH 0
400 #define SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH 0
401
402 OSStatus
403 SSLProcessCertificateRequest(SSLBuffer message, SSLContext *ctx)
404 {
405 unsigned i;
406 unsigned typeCount;
407 unsigned shListLen = 0;
408 UInt8 *charPtr;
409 unsigned dnListLen;
410 unsigned dnLen;
411 SSLBuffer dnBuf;
412 DNListElem *dn;
413 OSStatus err;
414
415 /*
416 * Cert request only happens in during client authentication.
417 * We'll send a client cert if we have an appropriate one, but
418 * we don't do any DNList compare.
419 */
420 unsigned minLen = (sslVersionIsLikeTls12(ctx)) ? 5 : 3;
421 if (message.length < minLen) {
422 sslErrorLog("SSLProcessCertificateRequest: length decode error 1\n");
423 return errSSLProtocol;
424 }
425 charPtr = message.data;
426 typeCount = *charPtr++;
427 if (typeCount < 1 || message.length < minLen + typeCount) {
428 sslErrorLog("SSLProcessCertificateRequest: length decode error 2\n");
429 return errSSLProtocol;
430 }
431 if(typeCount != 0) {
432 /* Store server-specified auth types */
433 if(ctx->clientAuthTypes != NULL) {
434 sslFree(ctx->clientAuthTypes);
435 }
436 ctx->clientAuthTypes = (SSLClientAuthenticationType *)
437 sslMalloc(typeCount * sizeof(SSLClientAuthenticationType));
438 for(i=0; i<typeCount; i++) {
439 sslLogNegotiateDebug("===Server specifies authType %d", (int)(*charPtr));
440 ctx->clientAuthTypes[i] = (SSLClientAuthenticationType)(*charPtr++);
441 }
442 ctx->numAuthTypes = typeCount;
443 }
444
445 if (sslVersionIsLikeTls12(ctx)) {
446 /* Parse the supported_signature_algorithms field added in TLS1.2 */
447 shListLen = SSLDecodeInt(charPtr, 2);
448 charPtr += 2;
449 if (message.length < minLen + typeCount + shListLen) {
450 sslErrorLog("SSLProcessCertificateRequest: length decode error 3\n");
451 return errSSLProtocol;
452 }
453
454 if (shListLen & 1) {
455 sslErrorLog("SSLProcessCertificateRequest: signAlg len odd\n");
456 return errSSLProtocol;
457 }
458 ctx->numServerSigAlgs = shListLen / 2;
459 if(ctx->serverSigAlgs != NULL) {
460 sslFree(ctx->serverSigAlgs);
461 }
462 ctx->serverSigAlgs = (SSLSignatureAndHashAlgorithm *)
463 sslMalloc((ctx->numServerSigAlgs) * sizeof(SSLSignatureAndHashAlgorithm));
464 for(i=0; i<ctx->numServerSigAlgs; i++) {
465 /* TODO: Validate hash and signature fields. */
466 ctx->serverSigAlgs[i].hash = *charPtr++;
467 ctx->serverSigAlgs[i].signature = *charPtr++;
468 sslLogNegotiateDebug("===Server specifies sigAlg %d %d",
469 ctx->serverSigAlgs[i].hash,
470 ctx->serverSigAlgs[i].signature);
471 }
472 }
473
474 /* if a client cert is set, it must match a server-specified auth type */
475 err = SSLUpdateNegotiatedClientAuthType(ctx);
476
477 /* obtain server's DNList */
478 dnListLen = SSLDecodeInt(charPtr, 2);
479 charPtr += 2;
480 if (message.length != minLen + typeCount + shListLen + dnListLen) {
481 sslErrorLog("SSLProcessCertificateRequest: length decode error 3\n");
482 return errSSLProtocol;
483 }
484 while (dnListLen > 0)
485 { if (dnListLen < 2) {
486 sslErrorLog("SSLProcessCertificateRequest: dnListLen error 1\n");
487 return errSSLProtocol;
488 }
489 dnLen = SSLDecodeInt(charPtr, 2);
490 charPtr += 2;
491 if (dnListLen < 2 + dnLen) {
492 sslErrorLog("SSLProcessCertificateRequest: dnListLen error 2\n");
493 return errSSLProtocol;
494 }
495 if ((err = SSLAllocBuffer(&dnBuf, sizeof(DNListElem), ctx)) != 0)
496 return err;
497 dn = (DNListElem*)dnBuf.data;
498 if ((err = SSLAllocBuffer(&dn->derDN, dnLen, ctx)) != 0)
499 { SSLFreeBuffer(&dnBuf, ctx);
500 return err;
501 }
502 memcpy(dn->derDN.data, charPtr, dnLen);
503 charPtr += dnLen;
504 dn->next = ctx->acceptableDNList;
505 ctx->acceptableDNList = dn;
506 dnListLen -= 2 + dnLen;
507 }
508
509 assert(charPtr == message.data + message.length);
510
511 return noErr;
512 }
513
514
515 /* TODO: this should be refactored with FindSigAlg in sslKeyExchange.c */
516 static
517 OSStatus FindCertSigAlg(SSLContext *ctx,
518 SSLSignatureAndHashAlgorithm *alg)
519 {
520 unsigned i;
521
522 assert(ctx->protocolSide == kSSLClientSide);
523 assert(ctx->negProtocolVersion >= TLS_Version_1_2);
524 assert(!ctx->isDTLS);
525
526 if((ctx->numServerSigAlgs==0) ||(ctx->serverSigAlgs==NULL))
527 return errSSLInternal;
528
529 for(i=0; i<ctx->numServerSigAlgs; i++) {
530 alg->hash = ctx->serverSigAlgs[i].hash;
531 alg->signature = ctx->serverSigAlgs[i].signature;
532 // We only support RSA cert for our own certs.
533 if(ctx->serverSigAlgs[i].signature != SSL_SignatureAlgorithmRSA)
534 continue;
535
536 //Let's only support SHA1 and SHA256. SHA384 does not work with 512 bits RSA keys
537 // We should actually test against what the client cert can do.
538 if((alg->hash==SSL_HashAlgorithmSHA1) || (alg->hash==SSL_HashAlgorithmSHA256)) {
539 return noErr;
540 }
541 }
542 // We could not find a supported signature and hash algorithm
543 return errSSLProtocol;
544 }
545
546 OSStatus
547 SSLEncodeCertificateVerify(SSLRecord *certVerify, SSLContext *ctx)
548 { OSStatus err;
549 UInt8 hashData[SSL_MAX_DIGEST_LEN];
550 SSLBuffer hashDataBuf;
551 size_t len;
552 size_t outputLen;
553 UInt8 *charPtr;
554 int head;
555 size_t maxSigLen;
556 bool isRSA = false;
557
558 certVerify->contents.data = 0;
559 hashDataBuf.data = hashData;
560 hashDataBuf.length = SSL_MAX_DIGEST_LEN;
561
562
563 assert(ctx->signingPrivKeyRef != NULL);
564 err = sslGetMaxSigSize(ctx->signingPrivKeyRef, &maxSigLen);
565 if(err) {
566 goto fail;
567 }
568
569 switch(ctx->negAuthType) {
570 case SSLClientAuth_RSASign:
571 isRSA = true;
572 break;
573 #if SSL_ENABLE_ECDSA_SIGN_AUTH
574 case SSLClientAuth_ECDSASign:
575 break;
576 #endif
577 default:
578 /* shouldn't be here */
579 assert(0);
580 return errSSLInternal;
581 }
582
583 certVerify->contentType = SSL_RecordTypeHandshake;
584 assert(ctx->negProtocolVersion >= SSL_Version_3_0);
585 certVerify->protocolVersion = ctx->negProtocolVersion;
586 head = SSLHandshakeHeaderSize(certVerify);
587
588 outputLen = maxSigLen + head + 2;
589
590 SSLSignatureAndHashAlgorithm sigAlg;
591
592 if (sslVersionIsLikeTls12(ctx)) {
593 err=FindCertSigAlg(ctx, &sigAlg);
594 if(err)
595 goto fail;
596 outputLen += 2;
597 }
598
599 assert(ctx->sslTslCalls != NULL);
600 if ((err = ctx->sslTslCalls->computeCertVfyMac(ctx, &hashDataBuf, sigAlg.hash)) != 0)
601 goto fail;
602
603 if ((err = SSLAllocBuffer(&certVerify->contents, outputLen, ctx)) != 0)
604 goto fail;
605
606 /* Sign now to get the actual length */
607 charPtr = certVerify->contents.data+head;
608
609 if (sslVersionIsLikeTls12(ctx))
610 {
611 *charPtr++ = sigAlg.hash;
612 *charPtr++ = sigAlg.signature;
613
614 /* We don't support anything but RSA for client side auth yet */
615 assert(isRSA);
616 SecAsn1AlgId algId;
617 switch (sigAlg.hash) {
618 case SSL_HashAlgorithmSHA384:
619 algId.algorithm = CSSMOID_SHA384WithRSA;
620 break;
621 case SSL_HashAlgorithmSHA256:
622 algId.algorithm = CSSMOID_SHA256WithRSA;
623 break;
624 case SSL_HashAlgorithmSHA1:
625 algId.algorithm = CSSMOID_SHA1WithRSA;
626 break;
627 default:
628 sslErrorLog("SSLEncodeCertificateVerify: unsupported signature hash algorithm (%d)\n",
629 sigAlg.hash);
630 assert(0); // if you get here, something is wrong in FindCertSigAlg
631 err=errSSLInternal;
632 goto fail;
633 }
634
635 err = sslRsaSign(ctx,
636 ctx->signingPrivKeyRef,
637 &algId,
638 hashData,
639 hashDataBuf.length,
640 charPtr+2,
641 maxSigLen,
642 &outputLen);
643 len=outputLen+2+2;
644 } else {
645 err = sslRawSign(ctx,
646 ctx->signingPrivKeyRef,
647 hashData, // data to sign
648 hashDataBuf.length, // Data to sign size
649 charPtr+2, // signature destination
650 maxSigLen, // we mallocd len+head+2
651 &outputLen);
652 len = outputLen+2;
653 }
654 if(err) {
655 sslErrorLog("SSLEncodeCertificateVerify: unable to sign data (error %d)\n", err);
656 goto fail;
657 }
658 // At this point:
659 // len = message length
660 // outputlen = sig length
661 certVerify->contents.length = len + head;
662
663 /* charPtr point at the len field here */
664 charPtr = SSLEncodeSize(charPtr, outputLen, 2);
665 charPtr = SSLEncodeHandshakeHeader(ctx, certVerify, SSL_HdskCertVerify, len);
666
667 assert(charPtr==(certVerify->contents.data+head));
668
669 err = noErr;
670
671 fail:
672
673 return err;
674 }
675
676 OSStatus
677 SSLProcessCertificateVerify(SSLBuffer message, SSLContext *ctx)
678 { OSStatus err;
679 UInt8 hashData[SSL_MAX_DIGEST_LEN];
680 size_t signatureLen;
681 SSLBuffer hashDataBuf;
682 size_t publicModulusLen;
683 uint8_t *charPtr = message.data;
684 uint8_t *endCp = charPtr + message.length;
685
686 SSLSignatureAndHashAlgorithm sigAlg;
687 SecAsn1AlgId algId;
688
689 if (ctx->isDTLS
690 ? ctx->negProtocolVersion < DTLS_Version_1_0
691 : ctx->negProtocolVersion >= TLS_Version_1_2) {
692 /* Parse the algorithm field added in TLS1.2 */
693 if((charPtr+2) > endCp) {
694 sslErrorLog("SSLProcessCertificateVerify: msg len error 1\n");
695 return errSSLProtocol;
696 }
697 sigAlg.hash = *charPtr++;
698 sigAlg.signature = *charPtr++;
699
700 switch (sigAlg.hash) {
701 case SSL_HashAlgorithmSHA256:
702 algId.algorithm = CSSMOID_SHA256WithRSA;
703 if(ctx->selectedCipherSpec.macAlgorithm->hmac->alg == HA_SHA384) {
704 sslErrorLog("SSLProcessCertificateVerify: inconsistent hash, HA_SHA384\n");
705 return errSSLInternal;
706 }
707 break;
708 case SSL_HashAlgorithmSHA384:
709 algId.algorithm = CSSMOID_SHA384WithRSA;
710 if(ctx->selectedCipherSpec.macAlgorithm->hmac->alg != HA_SHA384) {
711 sslErrorLog("SSLProcessCertificateVerify: inconsistent hash, %d not HA_SHA384\n", ctx->selectedCipherSpec.macAlgorithm->hmac->alg);
712 return errSSLInternal;
713 }
714 break;
715 default:
716 sslErrorLog("SSLProcessCertificateVerify: unsupported hash %d\n", sigAlg.hash);
717 return errSSLProtocol;
718 }
719 }
720
721 if ((charPtr + 2) > endCp) {
722 sslErrorLog("SSLProcessCertificateVerify: msg len error\n");
723 return errSSLProtocol;
724 }
725
726 signatureLen = SSLDecodeSize(charPtr, 2);
727 charPtr += 2;
728 if ((charPtr + signatureLen) > endCp) {
729 sslErrorLog("SSLProcessCertificateVerify: sig len error 1\n");
730 return errSSLProtocol;
731 }
732
733 publicModulusLen = sslPubKeyLengthInBytes(ctx->peerPubKey);
734
735 #if 0
736 if (signatureLen != publicModulusLen) {
737 sslErrorLog("SSLProcessCertificateVerify: sig len error 2\n");
738 return errSSLProtocol;
739 }
740 #endif
741 if (publicModulusLen == 0) {
742 sslErrorLog("SSLProcessCertificateVerify: pub key modulus is 0\n");
743 }
744
745 hashDataBuf.data = hashData;
746 hashDataBuf.length = SSL_MAX_DIGEST_LEN;
747
748 assert(ctx->sslTslCalls != NULL);
749 if ((err = ctx->sslTslCalls->computeCertVfyMac(ctx, &hashDataBuf, sigAlg.hash)) != 0)
750 goto fail;
751
752 if (sslVersionIsLikeTls12(ctx))
753 {
754 if(sigAlg.signature==SSL_SignatureAlgorithmRSA) {
755 err = sslRsaVerify(ctx,
756 ctx->peerPubKey,
757 &algId,
758 hashData,
759 hashDataBuf.length,
760 charPtr,
761 signatureLen);
762 } else {
763 err = sslRawVerify(ctx,
764 ctx->peerPubKey,
765 hashData,
766 hashDataBuf.length,
767 charPtr,
768 signatureLen);
769 }
770 } else {
771 /* sslRawVerify does the decrypt & compare for us in one shot. */
772 err = sslRawVerify(ctx,
773 ctx->peerPubKey,
774 hashData, // data to verify
775 hashDataBuf.length,
776 charPtr, // signature
777 signatureLen);
778 }
779
780 if(err) {
781 SSLFatalSessionAlert(SSL_AlertDecryptError, ctx);
782 goto fail;
783 }
784 err = noErr;
785
786 fail:
787 return err;
788 }