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/oidsalg.h>
44 #include "utilities/SecCFRelease.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)))
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");
137 return errSecSuccess
;
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
));
171 return errSecAllocate
;
173 if ((err
= SSLAllocBuffer(&cert
->derCert
, certLen
)
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
) {
187 return errSecAllocate
;
190 sslDebugLog("SSLProcessCertificate: releasing existing cert chain\n");
191 CFRelease(ctx
->peerCert
);
193 ctx
->peerCert
= certChain
;
195 cert
= SecCertificateCreateWithBytes(NULL
, p
, certLen
);
196 #if SSL_DEBUG && !TARGET_OS_IPHONE
198 /* print cert name when debugging; leave disabled otherwise */
199 CFStringRef certName
= NULL
;
200 OSStatus status
= SecCertificateInferLabel(cert
, &certName
);
202 if (status
|| !certName
|| !CFStringGetCString(certName
, buf
, 1024-1, kCFStringEncodingUTF8
)) { buf
[0]=0; }
203 sslDebugLog("SSLProcessCertificate: err=%d, received \"%s\" (%ld bytes)\n",(int) status
, buf
, certLen
);
204 CFReleaseSafe(certName
);
208 sslErrorLog("SSLProcessCertificate: unable to create cert ref from data\n");
209 return errSecAllocate
;
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.
228 return errSecSuccess
;
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
);
263 if (err
== errSecSuccess
) {
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
)))
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
);
395 return errSecSuccess
;
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
))))
497 dn
= (DNListElem
*)dnBuf
.data
;
498 if ((err
= SSLAllocBuffer(&dn
->derDN
, dnLen
)))
499 { SSLFreeBuffer(&dnBuf
);
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
);
511 return errSecSuccess
;
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
)) {
539 return errSecSuccess
;
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
)) != 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", (int)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
->selectedCipherSpecParams
.macAlg
== 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
->selectedCipherSpecParams
.macAlg
!= HA_SHA384
) {
711 sslErrorLog("SSLProcessCertificateVerify: inconsistent hash, %d not HA_SHA384\n", ctx
->selectedCipherSpecParams
.macAlg
);
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
);