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/oidsalg.h> 44#include "utilities/SecCFRelease.h" 45 46 47OSStatus 48SSLEncodeCertificate(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))) 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 errSecSuccess; 138} 139 140OSStatus 141SSLProcessCertificate(SSLBuffer message, SSLContext *ctx) 142{ 143 size_t listLen, certLen; 144 UInt8 *p; 145 OSStatus err; 146 CFMutableArrayRef certChain = NULL; 147 SecCertificateRef cert; 148 149 p = message.data; 150 listLen = SSLDecodeInt(p,3); 151 p += 3; 152 if (listLen + 3 != message.length) { 153 sslErrorLog("SSLProcessCertificate: length decode error 1\n"); 154 return errSSLProtocol; 155 } 156 157 while (listLen > 0) 158 { 159 if (listLen < 3) { 160 sslErrorLog("SSLProcessCertificate: length decode error 2\n"); 161 return errSSLProtocol; 162 } 163 certLen = SSLDecodeInt(p,3); 164 p += 3; 165 if (listLen < certLen + 3) { 166 sslErrorLog("SSLProcessCertificate: length decode error 3\n"); 167 return errSSLProtocol; 168 } 169 if (!certChain) { 170 certChain = CFArrayCreateMutable(kCFAllocatorDefault, 0, 171 &kCFTypeArrayCallBacks); 172 if (certChain == NULL) { 173 return errSecAllocate; 174 } 175 } 176 cert = SecCertificateCreateWithBytes(NULL, p, certLen); 177 #if SSL_DEBUG && !TARGET_OS_IPHONE 178 { 179 /* print cert name when debugging; leave disabled otherwise */ 180 CFStringRef certName = NULL; 181 OSStatus status = SecCertificateInferLabel(cert, &certName); 182 char buf[1024]; 183 if (status || !certName || !CFStringGetCString(certName, buf, 1024-1, kCFStringEncodingUTF8)) { buf[0]=0; } 184 sslDebugLog("SSLProcessCertificate: err=%d, received \"%s\" (%ld bytes)\n",(int) status, buf, certLen); 185 CFReleaseSafe(certName); 186 } 187 #endif 188 if (cert == NULL) { 189 sslErrorLog("SSLProcessCertificate: unable to create cert ref from data\n"); 190 return errSecAllocate; 191 } 192 p += certLen; 193 /* Insert forwards; root cert will be last in linked list */ 194 CFArrayAppendValue(certChain, cert); 195 CFRelease(cert); 196 listLen -= 3+certLen; 197 } 198 assert(p == message.data + message.length && listLen == 0); 199 200 if (ctx->protocolSide == kSSLClientSide && ctx->peerCert && !ctx->allowServerIdentityChange) { 201 // Do not accept a different server cert during renegotiation unless allowed. 202 if((certChain!=NULL) && !CFEqual(ctx->peerCert, certChain)) 203 { 204 CFRelease(certChain); 205 sslErrorLog("Illegal server identity change during renegotiation\n"); 206 return errSSLProtocol; 207 } 208 } 209 210 // Replace old cert with new cert. 211 if (ctx->peerCert) { 212 sslDebugLog("SSLProcessCertificate: releasing existing cert chain\n"); 213 CFRelease(ctx->peerCert); 214 } 215 216 ctx->peerCert = certChain; 217 218 if (!ctx->peerCert) { 219 /* this *might* be OK... */ 220 if((ctx->protocolSide == kSSLServerSide) && 221 (ctx->clientAuth != kAlwaysAuthenticate)) { 222 /* 223 * we tried to authenticate, client doesn't have a cert, and 224 * app doesn't require it. OK. 225 */ 226 return errSecSuccess; 227 } 228 else { 229 AlertDescription desc; 230 if(ctx->negProtocolVersion == SSL_Version_3_0) { 231 /* this one's for SSL3 only */ 232 desc = SSL_AlertBadCert; 233 } 234 else { 235 desc = SSL_AlertCertUnknown; 236 } 237 SSLFatalSessionAlert(desc, ctx); 238 return errSSLXCertChainInvalid; 239 } 240 } 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 == errSecSuccess) { 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 315OSStatus 316SSLEncodeCertificateRequest(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))) 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 errSecSuccess; 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 402OSStatus 403SSLProcessCertificateRequest(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)))) 496 return err; 497 dn = (DNListElem*)dnBuf.data; 498 if ((err = SSLAllocBuffer(&dn->derDN, dnLen))) 499 { SSLFreeBuffer(&dnBuf); 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 errSecSuccess; 512} 513 514 515/* TODO: this should be refactored with FindSigAlg in sslKeyExchange.c */ 516static 517OSStatus 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 errSecSuccess; 540 } 541 } 542 // We could not find a supported signature and hash algorithm 543 return errSSLProtocol; 544} 545 546OSStatus 547SSLEncodeCertificateVerify(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)) != 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", (int)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 = errSecSuccess; 670 671fail: 672 673 return err; 674} 675 676OSStatus 677SSLProcessCertificateVerify(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->selectedCipherSpecParams.macAlg == 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->selectedCipherSpecParams.macAlg != HA_SHA384) { 711 sslErrorLog("SSLProcessCertificateVerify: inconsistent hash, %d not HA_SHA384\n", ctx->selectedCipherSpecParams.macAlg); 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 = errSecSuccess; 785 786fail: 787 return err; 788} 789