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