2  * Copyright (c) 1999-2001,2005-2012 Apple Inc. All Rights Reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   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 
  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. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  25  * sslCert.c - certificate request/verify messages 
  29 #include "sslContext.h" 
  30 #include "sslHandshake.h" 
  31 #include "sslMemory.h" 
  32 #include "sslAlertMessage.h" 
  35 #include "sslDigests.h" 
  36 #include "sslCrypto.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> 
  48 SSLEncodeCertificate(SSLRecord 
*certificate
, SSLContext 
*ctx
) 
  53 #ifdef USE_SSLCERTIFICATE 
  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. 
  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. 
  69         assert(ctx
->negProtocolVersion 
>= SSL_Version_3_0
); 
  70         assert((ctx
->localCert 
!= NULL
) || (ctx
->negProtocolVersion 
>= TLS_Version_1_0
)); 
  73 #ifdef USE_SSLCERTIFICATE 
  75     cert 
= ctx
->localCert
; 
  77     {   totalLength 
+= 3 + cert
->derCert
.length
;    /* 3 for encoded length field */ 
  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 */ 
  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) 
  95     charPtr 
= SSLEncodeHandshakeHeader(ctx
, certificate
, SSL_HdskCert
, totalLength
+3); 
  97     charPtr 
= SSLEncodeSize(charPtr
, totalLength
, 3);      /* Vector length */ 
  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
) 
 106         charPtr 
= SSLEncodeSize(charPtr
, cert
->derCert
.length
, 3); 
 107         memcpy(charPtr
, cert
->derCert
.data
, cert
->derCert
.length
); 
 108         charPtr 
+= cert
->derCert
.length
; 
 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
; 
 122     assert(charPtr 
== certificate
->contents
.data 
+ certificate
->contents
.length
); 
 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). */ 
 130                 assert(ctx
->clientCertState 
== kSSLClientCertRequested
); 
 131                 assert(ctx
->certRequested
); 
 132                 ctx
->clientCertState 
= kSSLClientCertSent
; 
 135                 sslCertDebug("...sending empty cert msg"); 
 141 SSLProcessCertificate(SSLBuffer message
, SSLContext 
*ctx
) 
 143     size_t          listLen
, certLen
; 
 146 #ifdef USE_SSLCERTIFICATE 
 147     SSLCertificate      
*cert
; 
 149     CFMutableArrayRef   certChain 
= NULL
; 
 150     SecCertificateRef   cert
; 
 154     listLen 
= SSLDecodeInt(p
,3); 
 156     if (listLen 
+ 3 != message
.length
) { 
 157         sslErrorLog("SSLProcessCertificate: length decode error 1\n"); 
 158         return errSSLProtocol
; 
 162     {   certLen 
= SSLDecodeInt(p
,3); 
 164         if (listLen 
< certLen 
+ 3) { 
 165                 sslErrorLog("SSLProcessCertificate: length decode error 2\n"); 
 166             return errSSLProtocol
; 
 168 #ifdef USE_SSLCERTIFICATE 
 169                 cert 
= (SSLCertificate 
*)sslMalloc(sizeof(SSLCertificate
)); 
 173         if ((err 
= SSLAllocBuffer(&cert
->derCert
, certLen
, ctx
)) != 0) 
 177         memcpy(cert
->derCert
.data
, p
, certLen
); 
 179         cert
->next 
= ctx
->peerCert
;     /* Insert backwards; root cert 
 180                                                                                  * will be first in linked list */ 
 181         ctx
->peerCert 
= cert
; 
 184                         certChain 
= CFArrayCreateMutable(kCFAllocatorDefault
, 0, 
 185                                 &kCFTypeArrayCallBacks
); 
 186                         if (certChain 
== NULL
) { 
 190                                 sslDebugLog("SSLProcessCertificate: releasing existing cert chain\n"); 
 191                                 CFRelease(ctx
->peerCert
); 
 193                         ctx
->peerCert 
= certChain
; 
 195                 cert 
= SecCertificateCreateWithBytes(NULL
, p
, certLen
); 
 198                         /* print cert name when debugging; leave disabled otherwise */ 
 199                         CFStringRef certName 
= NULL
; 
 200                         OSStatus status 
= SecCertificateInferLabel(cert
, &certName
); 
 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
); 
 208                         sslErrorLog("SSLProcessCertificate: unable to create cert ref from data\n"); 
 212                 /* Insert forwards; root cert will be last in linked list */ 
 213                 CFArrayAppendValue(certChain
, cert
); 
 216         listLen 
-= 3+certLen
; 
 218     assert(p 
== message
.data 
+ message
.length 
&& listLen 
== 0); 
 220     if (!ctx
->peerCert
) { 
 221                 /* this *might* be OK... */ 
 222                 if((ctx
->protocolSide 
== kSSLServerSide
) && 
 223                    (ctx
->clientAuth 
!= kAlwaysAuthenticate
)) { 
 225                          * we tried to authenticate, client doesn't have a cert, and 
 226                          * app doesn't require it. OK. 
 231                         AlertDescription desc
; 
 232                         if(ctx
->negProtocolVersion 
== SSL_Version_3_0
) { 
 233                                 /* this one's for SSL3 only */ 
 234                                 desc 
= SSL_AlertBadCert
; 
 237                                 desc 
= SSL_AlertCertUnknown
; 
 239                         SSLFatalSessionAlert(desc
, ctx
); 
 240                         return errSSLXCertChainInvalid
; 
 244     if((err 
= sslVerifyCertChain(ctx
, ctx
->peerCert
, true)) != 0) { 
 245         AlertDescription desc
; 
 247         case errSSLUnknownRootCert
: 
 248         case errSSLNoRootCert
: 
 249             desc 
= SSL_AlertUnknownCA
; 
 251         case errSSLCertExpired
: 
 252         case errSSLCertNotYetValid
: 
 253             desc 
= SSL_AlertCertExpired
; 
 255         case errSSLXCertChainInvalid
: 
 257             desc 
= SSL_AlertCertUnknown
; 
 260         SSLFatalSessionAlert(desc
, ctx
); 
 264         if(ctx
->peerPubKey 
!= NULL
) { 
 265             /* renegotiating - free old key first */ 
 266             sslFreePubKey(&ctx
->peerPubKey
); 
 268         err 
= sslCopyPeerPubKey(ctx
, &ctx
->peerPubKey
); 
 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
) { 
 277              * Error could be from no cert (when we require one) 
 280             if(ctx
->peerCert 
!= NULL
) { 
 281                 ctx
->clientCertState 
= kSSLClientCertRejected
; 
 283         } else if(ctx
->peerCert 
!= NULL
) { 
 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 
 290             ctx
->clientCertState 
= kSSLClientCertSent
; 
 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. 
 298         if (ctx
->breakOnClientAuth
) { 
 299             ctx
->signalClientAuth 
= true; 
 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. 
 307         if (ctx
->breakOnServerAuth
) { 
 308             ctx
->signalServerAuth 
= true; 
 316 SSLEncodeCertificateRequest(SSLRecord 
*request
, SSLContext 
*ctx
) 
 319     size_t      shListLen 
= 0, dnListLen
, msgLen
; 
 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. 
 330     dn 
= ctx
->acceptableDNList
; 
 332     {   dnListLen 
+= 2 + dn
->derDN
.length
; 
 335     msgLen 
= 1 +        // number of cert types 
 337              shListLen 
+  // SignatureAlgorithms 
 338                          2 +    // length of DN list 
 341     request
->contentType 
= SSL_RecordTypeHandshake
; 
 342     assert(ctx
->negProtocolVersion 
>= SSL_Version_3_0
); 
 344     request
->protocolVersion 
= ctx
->negProtocolVersion
; 
 345     head 
= SSLHandshakeHeaderSize(request
); 
 346     if ((err 
= SSLAllocBuffer(&request
->contents
, msgLen 
+ head
, ctx
)) != 0) 
 349     charPtr 
= SSLEncodeHandshakeHeader(ctx
, request
, SSL_HdskCertRequest
, msgLen
); 
 351     *charPtr
++ = 2;        /* two cert types */ 
 352     *charPtr
++ = SSLClientAuth_RSASign
; 
 353     *charPtr
++ = SSLClientAuth_ECDSASign
; 
 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
; 
 385     charPtr 
= SSLEncodeSize(charPtr
, dnListLen
, 2); 
 386     dn 
= ctx
->acceptableDNList
; 
 388     {   charPtr 
= SSLEncodeSize(charPtr
, dn
->derDN
.length
, 2); 
 389         memcpy(charPtr
, dn
->derDN
.data
, dn
->derDN
.length
); 
 390         charPtr 
+= dn
->derDN
.length
; 
 394     assert(charPtr 
== request
->contents
.data 
+ request
->contents
.length
); 
 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 
 403 SSLProcessCertificateRequest(SSLBuffer message
, SSLContext 
*ctx
) 
 407     unsigned            shListLen 
= 0; 
 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. 
 420     unsigned minLen 
= (sslVersionIsLikeTls12(ctx
)) ? 5 : 3; 
 421     if (message
.length 
< minLen
) { 
 422         sslErrorLog("SSLProcessCertificateRequest: length decode error 1\n"); 
 423         return errSSLProtocol
; 
 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
; 
 432                 /* Store server-specified auth types */ 
 433                 if(ctx
->clientAuthTypes 
!= NULL
) { 
 434                         sslFree(ctx
->clientAuthTypes
); 
 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
++); 
 442                 ctx
->numAuthTypes 
= typeCount
; 
 445     if (sslVersionIsLikeTls12(ctx
)) { 
 446         /* Parse the supported_signature_algorithms field added in TLS1.2 */ 
 447         shListLen 
= SSLDecodeInt(charPtr
, 2); 
 449         if (message
.length 
< minLen 
+ typeCount 
+ shListLen
) { 
 450             sslErrorLog("SSLProcessCertificateRequest: length decode error 3\n"); 
 451             return errSSLProtocol
; 
 455             sslErrorLog("SSLProcessCertificateRequest: signAlg len odd\n"); 
 456             return errSSLProtocol
; 
 458                 ctx
->numServerSigAlgs 
= shListLen 
/ 2; 
 459                 if(ctx
->serverSigAlgs 
!= NULL
) { 
 460                         sslFree(ctx
->serverSigAlgs
); 
 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
); 
 474         /* if a client cert is set, it must match a server-specified auth type */ 
 475         err 
= SSLUpdateNegotiatedClientAuthType(ctx
); 
 477         /* obtain server's DNList */ 
 478     dnListLen 
= SSLDecodeInt(charPtr
, 2); 
 480     if (message
.length 
!= minLen 
+ typeCount 
+ shListLen 
+ dnListLen
) { 
 481         sslErrorLog("SSLProcessCertificateRequest: length decode error 3\n"); 
 482         return errSSLProtocol
; 
 484     while (dnListLen 
> 0) 
 485     {   if (dnListLen 
< 2) { 
 486                 sslErrorLog("SSLProcessCertificateRequest: dnListLen error 1\n"); 
 487             return errSSLProtocol
; 
 489         dnLen 
= SSLDecodeInt(charPtr
, 2); 
 491         if (dnListLen 
< 2 + dnLen
) { 
 492                 sslErrorLog("SSLProcessCertificateRequest: dnListLen error 2\n"); 
 493                 return errSSLProtocol
; 
 495         if ((err 
= SSLAllocBuffer(&dnBuf
, sizeof(DNListElem
), ctx
)) != 0) 
 497         dn 
= (DNListElem
*)dnBuf
.data
; 
 498         if ((err 
= SSLAllocBuffer(&dn
->derDN
, dnLen
, ctx
)) != 0) 
 499         {   SSLFreeBuffer(&dnBuf
, ctx
); 
 502         memcpy(dn
->derDN
.data
, charPtr
, dnLen
); 
 504         dn
->next 
= ctx
->acceptableDNList
; 
 505         ctx
->acceptableDNList 
= dn
; 
 506         dnListLen 
-= 2 + dnLen
; 
 509     assert(charPtr 
== message
.data 
+ message
.length
); 
 515 /* TODO: this should be refactored with FindSigAlg in sslKeyExchange.c */ 
 517 OSStatus 
FindCertSigAlg(SSLContext 
*ctx
, 
 518                         SSLSignatureAndHashAlgorithm 
*alg
) 
 522     assert(ctx
->protocolSide 
== kSSLClientSide
); 
 523     assert(ctx
->negProtocolVersion 
>= TLS_Version_1_2
); 
 524     assert(!ctx
->isDTLS
); 
 526     if((ctx
->numServerSigAlgs
==0) ||(ctx
->serverSigAlgs
==NULL
)) 
 527         return errSSLInternal
; 
 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
) 
 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
)) { 
 542     // We could not find a supported signature and hash algorithm 
 543     return errSSLProtocol
; 
 547 SSLEncodeCertificateVerify(SSLRecord 
*certVerify
, SSLContext 
*ctx
) 
 549     UInt8           hashData
[SSL_MAX_DIGEST_LEN
]; 
 550     SSLBuffer       hashDataBuf
; 
 558     certVerify
->contents
.data 
= 0; 
 559     hashDataBuf
.data 
= hashData
; 
 560     hashDataBuf
.length 
= SSL_MAX_DIGEST_LEN
; 
 563         assert(ctx
->signingPrivKeyRef 
!= NULL
); 
 564     err 
= sslGetMaxSigSize(ctx
->signingPrivKeyRef
, &maxSigLen
); 
 569         switch(ctx
->negAuthType
) { 
 570                 case SSLClientAuth_RSASign
: 
 573 #if SSL_ENABLE_ECDSA_SIGN_AUTH 
 574                 case SSLClientAuth_ECDSASign
: 
 578                         /* shouldn't be here */ 
 580                         return errSSLInternal
; 
 583     certVerify
->contentType 
= SSL_RecordTypeHandshake
; 
 584         assert(ctx
->negProtocolVersion 
>= SSL_Version_3_0
); 
 585     certVerify
->protocolVersion 
= ctx
->negProtocolVersion
; 
 586     head 
= SSLHandshakeHeaderSize(certVerify
); 
 588     outputLen 
= maxSigLen 
+ head 
+ 2; 
 590     SSLSignatureAndHashAlgorithm sigAlg
; 
 592     if (sslVersionIsLikeTls12(ctx
)) { 
 593         err
=FindCertSigAlg(ctx
, &sigAlg
); 
 599     assert(ctx
->sslTslCalls 
!= NULL
); 
 600     if ((err 
= ctx
->sslTslCalls
->computeCertVfyMac(ctx
, &hashDataBuf
, sigAlg
.hash
)) != 0) 
 603     if ((err 
= SSLAllocBuffer(&certVerify
->contents
, outputLen
, ctx
)) != 0) 
 606     /* Sign now to get the actual length */ 
 607     charPtr 
= certVerify
->contents
.data
+head
; 
 609     if (sslVersionIsLikeTls12(ctx
)) 
 611         *charPtr
++ = sigAlg
.hash
; 
 612         *charPtr
++ = sigAlg
.signature
; 
 614         /* We don't support anything but RSA for client side auth yet */ 
 617         switch (sigAlg
.hash
) { 
 618             case SSL_HashAlgorithmSHA384
: 
 619                 algId
.algorithm 
= CSSMOID_SHA384WithRSA
; 
 621             case SSL_HashAlgorithmSHA256
: 
 622                 algId
.algorithm 
= CSSMOID_SHA256WithRSA
; 
 624             case SSL_HashAlgorithmSHA1
: 
 625                 algId
.algorithm 
= CSSMOID_SHA1WithRSA
; 
 628                                 sslErrorLog("SSLEncodeCertificateVerify: unsupported signature hash algorithm (%d)\n", 
 630                 assert(0);          // if you get here, something is wrong in FindCertSigAlg 
 635         err 
= sslRsaSign(ctx
, 
 636                          ctx
->signingPrivKeyRef
, 
 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 
 655                 sslErrorLog("SSLEncodeCertificateVerify: unable to sign data (error %d)\n", err
); 
 659     //  len = message length 
 660     //  outputlen = sig length 
 661         certVerify
->contents
.length 
= len 
+ head
; 
 663     /* charPtr point at the len field here */ 
 664     charPtr 
= SSLEncodeSize(charPtr
, outputLen
, 2); 
 665     charPtr 
= SSLEncodeHandshakeHeader(ctx
, certVerify
, SSL_HdskCertVerify
, len
); 
 667     assert(charPtr
==(certVerify
->contents
.data
+head
)); 
 677 SSLProcessCertificateVerify(SSLBuffer message
, SSLContext 
*ctx
) 
 679     UInt8           hashData
[SSL_MAX_DIGEST_LEN
]; 
 681     SSLBuffer       hashDataBuf
; 
 682     size_t          publicModulusLen
; 
 683     uint8_t         *charPtr 
= message
.data
; 
 684         uint8_t         *endCp 
= charPtr 
+ message
.length
; 
 686     SSLSignatureAndHashAlgorithm    sigAlg
; 
 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
; 
 697         sigAlg
.hash 
= *charPtr
++; 
 698         sigAlg
.signature 
= *charPtr
++; 
 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
; 
 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
; 
 716                 sslErrorLog("SSLProcessCertificateVerify: unsupported hash %d\n", sigAlg
.hash
); 
 717                 return errSSLProtocol
; 
 721     if ((charPtr 
+ 2) > endCp
) { 
 722         sslErrorLog("SSLProcessCertificateVerify: msg len error\n"); 
 723         return errSSLProtocol
; 
 726     signatureLen 
= SSLDecodeSize(charPtr
, 2); 
 728     if ((charPtr 
+ signatureLen
) > endCp
) { 
 729         sslErrorLog("SSLProcessCertificateVerify: sig len error 1\n"); 
 730         return errSSLProtocol
; 
 733         publicModulusLen 
= sslPubKeyLengthInBytes(ctx
->peerPubKey
); 
 736     if (signatureLen 
!= publicModulusLen
) { 
 737         sslErrorLog("SSLProcessCertificateVerify: sig len error 2\n"); 
 738         return errSSLProtocol
; 
 741         if (publicModulusLen 
== 0) { 
 742                 sslErrorLog("SSLProcessCertificateVerify: pub key modulus is 0\n"); 
 745     hashDataBuf
.data 
= hashData
; 
 746     hashDataBuf
.length 
= SSL_MAX_DIGEST_LEN
; 
 748         assert(ctx
->sslTslCalls 
!= NULL
); 
 749     if ((err 
= ctx
->sslTslCalls
->computeCertVfyMac(ctx
, &hashDataBuf
, sigAlg
.hash
)) != 0) 
 752     if (sslVersionIsLikeTls12(ctx
)) 
 754         if(sigAlg
.signature
==SSL_SignatureAlgorithmRSA
) { 
 755             err 
= sslRsaVerify(ctx
, 
 763             err 
= sslRawVerify(ctx
, 
 771         /* sslRawVerify does the decrypt & compare for us in one shot. */ 
 772         err 
= sslRawVerify(ctx
, 
 774             hashData
,                           // data to verify 
 776             charPtr
,            // signature 
 781                 SSLFatalSessionAlert(SSL_AlertDecryptError
, ctx
);