/ lib / sslCert.c
sslCert.c
  1  /*
  2   * Copyright (c) 1999-2001,2005-2012 Apple Inc. All Rights Reserved.
  3   *
  4   * @APPLE_LICENSE_HEADER_START@
  5   *
  6   * This file contains Original Code and/or Modifications of Original Code
  7   * as defined in and that are subject to the Apple Public Source License
  8   * Version 2.0 (the 'License'). You may not use this file except in
  9   * compliance with the License. Please obtain a copy of the License at
 10   * http://www.opensource.apple.com/apsl/ and read it before using this
 11   * file.
 12   *
 13   * The Original Code and all software distributed under the License are
 14   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 15   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 16   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 17   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 18   * Please see the License for the specific language governing rights and
 19   * limitations under the License.
 20   *
 21   * @APPLE_LICENSE_HEADER_END@
 22   */
 23  
 24  /*
 25   * sslCert.c - certificate request/verify messages
 26   */
 27  
 28  #include "tls_handshake_priv.h"
 29  #include "sslHandshake.h"
 30  #include "sslHandshake_priv.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  
 41  int SSLFreeCertificates(SSLCertificate *certs)
 42  {
 43      return tls_free_buffer_list((tls_buffer_list_t *)certs);
 44  }
 45  
 46  int SSLFreeDNList(DNListElem *dn)
 47  {
 48      return tls_free_buffer_list((tls_buffer_list_t *)dn);
 49  }
 50  
 51  int
 52  SSLEncodeCertificate(tls_buffer *certificate, tls_handshake_t ctx)
 53  {
 54      int                 err;
 55      size_t              totalLength;
 56      uint8_t             *charPtr;
 57      int                 certCount;
 58      SSLCertificate      *cert;
 59      int                 head;
 60  
 61      /*
 62  	 * Note this can be called with localCert==0 for client side in TLS1+ and DTLS;
 63  	 * in that case we send an empty cert msg.
 64  	 */
 65  	assert(ctx->negProtocolVersion >= tls_protocol_version_SSL_3);
 66  	assert((ctx->localCert != NULL) || (ctx->negProtocolVersion >= tls_protocol_version_TLS_1_0));
 67      totalLength = 0;
 68      certCount = 0;
 69  
 70      /* If we are the client and didn't select an auth type, we will send an empty message */
 71      if(ctx->isServer || ctx->negAuthType != tls_client_auth_type_None) {
 72          cert = ctx->localCert;
 73          while (cert)
 74          {   totalLength += 3 + cert->derCert.length;    /* 3 for encoded length field */
 75              ++certCount;
 76              cert = cert->next;
 77          }
 78          cert = ctx->localCert;
 79      } else {
 80          certCount = 0;
 81          cert = NULL;
 82      }
 83  
 84      head = SSLHandshakeHeaderSize(ctx);
 85      if ((err = SSLAllocBuffer(certificate, totalLength + head + 3)))
 86          return err;
 87  
 88      charPtr = SSLEncodeHandshakeHeader(ctx, certificate, SSL_HdskCert, totalLength+3);
 89  
 90      charPtr = SSLEncodeSize(charPtr, totalLength, 3);      /* Vector length */
 91  
 92      /* Leaf cert is first in the linked list */
 93      while(cert) {
 94          charPtr = SSLEncodeSize(charPtr, cert->derCert.length, 3);
 95          memcpy(charPtr, cert->derCert.data, cert->derCert.length);
 96          charPtr += cert->derCert.length;
 97          cert = cert->next;
 98      }
 99  
100      assert(charPtr == certificate->data + certificate->length);
101  
102      if ((!ctx->isServer) && (ctx->negAuthType != tls_client_auth_type_None)) {
103  		/* this tells us to send a CertificateVerify msg after the
104  		 * client key exchange. We skip the cert vfy if we just
105  		 * sent an empty cert msg (i.e., we were asked for a cert
106  		 * but we don't have one). */
107          ctx->certSent = 1;
108  		assert(ctx->clientCertState == kSSLClientCertRequested);
109  		assert(ctx->certRequested);
110  		ctx->clientCertState = kSSLClientCertSent;
111  	}
112  	if(certCount == 0) {
113  		sslCertDebug("...sending empty cert msg");
114  	}
115      return errSSLSuccess;
116  }
117  
118  static bool
119  CertificateChainEqual(SSLCertificate *cert1, SSLCertificate *cert2)
120  {
121      do {
122          if(cert1 == NULL || cert2 == NULL)
123              return false;
124          if(cert1->derCert.length != cert2->derCert.length)
125              return false;
126          if(memcmp(cert1->derCert.data, cert2->derCert.data, cert1->derCert.length) != 0)
127              return false;
128          cert1 = cert1->next;
129          cert2 = cert2->next;
130      } while (cert1 != NULL || cert2 != NULL);
131  
132      return true;
133  }
134  
135  static const char base64_chars[] =
136      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
137  
138  
139  static void
140  debug_log_chain(const char *scope, SSLCertificate *cert)
141  {
142      size_t n, m, count = 0;
143      while(cert) {
144          char line[65];
145          uint32_t c;
146  
147          ssl_secdebug(scope, "cert: %lu", (unsigned long)count++);
148          ssl_secdebug(scope, "-----BEGIN CERTIFICATE-----");
149          m = n = 0;
150          while (n < cert->derCert.length) {
151              c = cert->derCert.data[n];
152              n++;
153  
154              c = c << 8;
155              if (n < cert->derCert.length)
156                  c |= cert->derCert.data[n];
157              n++;
158  
159              c = c << 8;
160              if (n < cert->derCert.length)
161                  c |= cert->derCert.data[n];
162              n++;
163  
164              line[m++] = base64_chars[(c & 0x00fc0000) >> 18];
165              line[m++] = base64_chars[(c & 0x0003f000) >> 12];
166              if (n > cert->derCert.length + 1)
167                  line[m++] = '=';
168              else
169                  line[m++] = base64_chars[(c & 0x00000fc0) >> 6];
170              if (n > cert->derCert.length)
171                  line[m++] = '=';
172              else
173                  line[m++] = base64_chars[(c & 0x0000003f) >> 0];
174              if (m == sizeof(line) - 1) {
175                  line[sizeof(line) - 1] = '\0';
176                  ssl_secdebug(scope, "%s", line);
177                  m = 0;
178              }
179              assert(m < sizeof(line) - 1);
180          }
181          if (m) {
182              line[m] = '\0';
183              ssl_secdebug(scope, "%s", line);
184          }
185          ssl_secdebug(scope, "-----END CERTIFICATE-----");
186  
187          cert = cert->next;
188      }
189  }
190  
191  int
192  SSLProcessCertificate(tls_buffer message, tls_handshake_t ctx)
193  {
194      size_t          listLen;
195      UInt8           *p;
196      int        err = 0;
197      SSLCertificate *certChain;
198  
199      if (message.length < 3) {
200          sslErrorLog("SSLProcessCertificate: message length decode error\n");
201          return errSSLProtocol;
202      }
203  
204      p = message.data;
205      listLen = SSLDecodeInt(p,3);
206      p += 3;
207      if (listLen + 3 != message.length) {
208      	sslErrorLog("SSLProcessCertificate: length decode error 1\n");
209          return errSSLProtocol;
210      }
211  
212      // Note: An empty certificate list (listLen==0) is allowed by the TLS RFC,
213      // but empty certificates (certLen==0) are not. Section 7.4.2 in RFC 5246
214      // defines the message syntax as such:
215      //
216      //  opaque ASN.1Cert<1..2^24-1>;
217      //
218      //  struct {
219      //        ASN.1Cert certificate_list<0..2^24-1>;
220      //  } Certificate;
221      //
222      // Note the difference between <1..2^24-1> and <0..2^24-1>
223      //
224  
225      if((err = SSLDecodeBufferList(p, listLen, 3, (tls_buffer_list_t **)&certChain))) {
226          return err;
227      }
228      p+=listLen;
229  
230      /* Do not accept a different server cert during renegotiation unless allowed */
231      if(!ctx->allowServerIdentityChange && ctx->peerCert && !CertificateChainEqual(ctx->peerCert, certChain)) {
232          sslErrorLog("Illegal server identity change during renegotiation\n");
233          SSLFreeCertificates(certChain);
234          return errSSLProtocol;
235      }
236  
237      if (ctx->peerCert == NULL && __ssl_debug_enabled("sslLogNegotiateDebug")) {
238          debug_log_chain("sslLogNegotiateDebug", certChain);
239      }
240  
241      /* Free certs if they already exist */
242      SSLFreeCertificates(ctx->peerCert);
243      ctx->peerCert=certChain;
244  
245      assert(p == message.data + message.length);
246  
247      /* Don't fail here if peerCert is NULL.
248         An empty Certificate message is valid in some cases.
249         The rest of the stack will handle it. */
250  
251      return err;
252  }
253  
254  
255  int
256  SSLEncodeCertificateStatus(tls_buffer *status, tls_handshake_t ctx)
257  {
258      int                 err;
259      size_t              totalLength;
260      uint8_t             *charPtr;
261      int                 head;
262  
263      assert(ctx->isServer);
264      assert(ctx->ocsp_enabled && ctx->ocsp_peer_enabled);
265  
266      if(ctx->ocsp_response.length==0) {
267          return errSSLInternal;
268      }
269  
270      totalLength = 1 + 3 + ctx->ocsp_response.length;
271  
272      head = SSLHandshakeHeaderSize(ctx);
273  
274      if ((err = SSLAllocBuffer(status, totalLength + head)))
275          return err;
276  
277      charPtr = SSLEncodeHandshakeHeader(ctx, status, SSL_HdskCertificateStatus, totalLength);
278  
279      *charPtr++ = SSL_CST_Ocsp;
280      charPtr = SSLEncodeSize(charPtr, ctx->ocsp_response.length, 3);
281      memcpy(charPtr, ctx->ocsp_response.data, ctx->ocsp_response.length);
282  
283      return 0;
284  }
285  
286  int
287  SSLProcessCertificateStatus(tls_buffer message, tls_handshake_t ctx)
288  {
289      uint8_t status_type;
290      uint8_t *p = message.data;
291      assert(!ctx->isServer);
292  
293      if (message.length < 1) {
294          sslErrorLog("SSLProcessCertificateStatus: message length decode error (1)\n");
295          return errSSLProtocol;
296      }
297  
298      status_type = *p++;
299  
300      if(status_type!=SSL_CST_Ocsp) {
301          return noErr;
302      }
303  
304      if (message.length < 3) {
305          sslErrorLog("SSLProcessCertificateStatus: message length decode error (2)\n");
306          return errSSLProtocol;
307      }
308  
309      size_t OCSPResponseLen = SSLDecodeSize(p, 3); p+=3;
310  
311      if(OCSPResponseLen==0) {
312          sslErrorLog("SSLProcessCertificateStatus: message length decode error (3)\n");
313          return errSSLProtocol;
314      }
315  
316      if(OCSPResponseLen+4 != message.length) {
317          sslErrorLog("SSLProcessCertificateStatus: message length decode error (4)\n");
318          return errSSLProtocol;
319      }
320  
321      ctx->ocsp_response_received = true;
322  
323      SSLFreeBuffer(&ctx->ocsp_response);
324      return SSLCopyBufferFromData(p, OCSPResponseLen, &ctx->ocsp_response);
325  }
326  
327  int
328  SSLEncodeCertificateRequest(tls_buffer *request, tls_handshake_t ctx)
329  {
330  	int    err;
331      size_t      shListLen = 0, dnListLen, msgLen;
332      UInt8       *charPtr;
333      DNListElem  *dn;
334      int         head;
335  
336  	assert(ctx->isServer);
337      if (sslVersionIsLikeTls12(ctx)) {
338          shListLen = 2 + 2 * ctx->numLocalSigAlgs;
339      }
340  
341  	dnListLen = 0;
342      dn = ctx->acceptableDNList;
343      while (dn)
344      {   dnListLen += 2 + dn->derDN.length;
345          dn = dn->next;
346      }
347      msgLen = 1 +	// number of cert types
348  			 2 +	// cert types
349               shListLen +  // SignatureAlgorithms
350  			 2 +	// length of DN list
351  			 dnListLen;
352  
353      assert(ctx->negProtocolVersion >= tls_protocol_version_SSL_3);
354  
355      head = SSLHandshakeHeaderSize(ctx);
356      if ((err = SSLAllocBuffer(request, msgLen + head)))
357          return err;
358  
359      charPtr = SSLEncodeHandshakeHeader(ctx, request, SSL_HdskCertRequest, msgLen);
360  
361      *charPtr++ = 2;        /* two cert types */
362      *charPtr++ = tls_client_auth_type_RSASign;
363      *charPtr++ = tls_client_auth_type_ECDSASign;
364  
365      if (shListLen) {
366          /* Encode the supported_signature_algorithms added in TLS1.2 */
367          charPtr = SSLEncodeSize(charPtr, shListLen - 2, 2);
368          for(int i=0; i<ctx->numLocalSigAlgs; i++) {
369              charPtr = SSLEncodeInt(charPtr, ctx->localSigAlgs[i].hash, 1);
370              charPtr = SSLEncodeInt(charPtr, ctx->localSigAlgs[i].signature, 1);
371          }
372      }
373  
374      charPtr = SSLEncodeSize(charPtr, dnListLen, 2);
375      dn = ctx->acceptableDNList;
376      while (dn)
377      {   charPtr = SSLEncodeSize(charPtr, dn->derDN.length, 2);
378          memcpy(charPtr, dn->derDN.data, dn->derDN.length);
379          charPtr += dn->derDN.length;
380          dn = dn->next;
381      }
382  
383      assert(charPtr == request->data + request->length);
384      return errSSLSuccess;
385  }
386  
387  int
388  SSLProcessCertificateRequest(tls_buffer message, tls_handshake_t ctx)
389  {
390      unsigned        i;
391      unsigned	    typeCount;
392      unsigned		shListLen = 0;
393      UInt8           *charPtr;
394      unsigned		dnListLen;
395  	unsigned		dnLen;
396      tls_buffer		dnBuf;
397      DNListElem		*dn;
398  	int		err;
399  
400      /*
401       * Cert request only happens in during client authentication.
402       * Application can send a client cert if they have an appropriate one.
403       * coreTLS does not ensure the client cert is appropriate.
404       */
405  
406      unsigned minLen = (sslVersionIsLikeTls12(ctx)) ? 5 : 3;
407      if (message.length < minLen) {
408      	sslErrorLog("SSLProcessCertificateRequest: length decode error 1\n");
409          return errSSLProtocol;
410      }
411      charPtr = message.data;
412      typeCount = *charPtr++;
413      if ((typeCount < 1) || (message.length < minLen + typeCount)) {
414      	sslErrorLog("SSLProcessCertificateRequest: length decode error 2\n");
415          return errSSLProtocol;
416      }
417  
418      /* Update the server-specified auth types */
419      sslFree(ctx->clientAuthTypes);
420      ctx->numAuthTypes = typeCount;
421      ctx->clientAuthTypes = (tls_client_auth_type *)
422                             sslMalloc(ctx->numAuthTypes * sizeof(tls_client_auth_type));
423      if(ctx->clientAuthTypes==NULL)
424          return errSSLInternal;
425  
426      for(i=0; i<ctx->numAuthTypes; i++) {
427          sslLogNegotiateDebug("===Server specifies authType %d", (int)(*charPtr));
428          ctx->clientAuthTypes[i] = (tls_client_auth_type)(*charPtr++);
429      }
430  
431      if (sslVersionIsLikeTls12(ctx)) {
432          /* Parse the supported_signature_algorithms field added in TLS1.2 */
433          shListLen = SSLDecodeInt(charPtr, 2);
434          charPtr += 2;
435          if ((shListLen < 2) || (message.length < minLen + typeCount + shListLen)) {
436              sslErrorLog("SSLProcessCertificateRequest: length decode error 3\n");
437              return errSSLProtocol;
438          }
439  
440          if (shListLen & 1) {
441              sslErrorLog("SSLProcessCertificateRequest: signAlg len odd\n");
442              return errSSLProtocol;
443          }
444  
445          sslFree(ctx->peerSigAlgs);
446          ctx->numPeerSigAlgs = shListLen / 2;
447          ctx->peerSigAlgs = (tls_signature_and_hash_algorithm *)
448                                sslMalloc((ctx->numPeerSigAlgs) * sizeof(tls_signature_and_hash_algorithm));
449          if(ctx->peerSigAlgs==NULL)
450              return errSSLInternal;
451  
452          for(i=0; i<ctx->numPeerSigAlgs; i++) {
453              ctx->peerSigAlgs[i].hash = *charPtr++;
454              ctx->peerSigAlgs[i].signature = *charPtr++;
455              sslLogNegotiateDebug("===Server specifies sigAlg %d %d",
456                                   ctx->peerSigAlgs[i].hash,
457                                   ctx->peerSigAlgs[i].signature);
458          }
459      }
460  
461      /* Update the acceptable DNList */
462      SSLFreeDNList(ctx->acceptableDNList);
463      ctx->acceptableDNList=NULL;
464  
465      dnListLen = SSLDecodeInt(charPtr, 2);
466      charPtr += 2;
467      if (message.length != minLen + typeCount + shListLen + dnListLen) {
468      	sslErrorLog("SSLProcessCertificateRequest: length decode error 3\n");
469          return errSSLProtocol;
470  	}
471      while (dnListLen > 0)
472      {   if (dnListLen < 2) {
473  		sslErrorLog("SSLProcessCertificateRequest: dnListLen error 1\n");
474              return errSSLProtocol;
475          }
476          dnLen = SSLDecodeInt(charPtr, 2);
477          charPtr += 2;
478          if (dnListLen < 2 + dnLen) {
479       		sslErrorLog("SSLProcessCertificateRequest: dnListLen error 2\n");
480             	return errSSLProtocol;
481      	}
482          if ((err = SSLAllocBuffer(&dnBuf, sizeof(DNListElem))))
483              return err;
484          dn = (DNListElem*)dnBuf.data;
485          if ((err = SSLAllocBuffer(&dn->derDN, dnLen)))
486          {   SSLFreeBuffer(&dnBuf);
487              return err;
488          }
489          memcpy(dn->derDN.data, charPtr, dnLen);
490          charPtr += dnLen;
491          dn->next = ctx->acceptableDNList;
492          ctx->acceptableDNList = dn;
493          dnListLen -= 2 + dnLen;
494      }
495  
496      assert(charPtr == message.data + message.length);
497  
498      return errSSLSuccess;
499  }
500  
501  
502  /* TODO: this should be refactored with FindSigAlg in sslKeyExchange.c */
503  static
504  int FindCertSigAlg(tls_handshake_t ctx, tls_signature_and_hash_algorithm *alg)
505  {
506  	assert(!ctx->isServer);
507      assert(ctx->negProtocolVersion >= tls_protocol_version_TLS_1_2);
508      assert(!ctx->isDTLS);
509  
510      if((ctx->numPeerSigAlgs==0) || (ctx->numLocalSigAlgs==0)) {
511          assert(0);
512          return errSSLInternal;
513      }
514  
515      //Check for matching server signature algorithm and corresponding hash algorithm
516      for(int i=0; i<ctx->numLocalSigAlgs; i++) {
517          if (alg->signature != ctx->localSigAlgs[i].signature)
518              continue;
519          alg->hash = ctx->localSigAlgs[i].hash;
520          for(int j=0; j<ctx->numPeerSigAlgs; j++) {
521              if (alg->signature != ctx->peerSigAlgs[j].signature)
522                  continue;
523              if(alg->hash == ctx->peerSigAlgs[j].hash) {
524                  return errSSLSuccess;
525              }
526          }
527      }
528  
529      // We could not find a supported signature and hash algorithm
530      return errSSLProtocol;
531  }
532  
533  int
534  SSLEncodeCertificateVerify(tls_buffer *certVerify, tls_handshake_t ctx)
535  {   int        err;
536      UInt8           hashData[SSL_MAX_DIGEST_LEN];
537      tls_buffer       hashDataBuf;
538      size_t          len;
539      size_t		    outputLen;
540      UInt8           *charPtr;
541      int             head;
542      size_t          maxSigLen;
543  
544      certVerify->data = 0;
545      hashDataBuf.data = hashData;
546      hashDataBuf.length = SSL_MAX_DIGEST_LEN;
547  
548  
549  	assert(ctx->signingPrivKeyRef != NULL);
550      err = sslGetMaxSigSize(ctx->signingPrivKeyRef, &maxSigLen);
551      if(err) {
552          goto fail;
553      }
554  
555      tls_signature_and_hash_algorithm sigAlg = {0,};
556  
557  	switch(ctx->signingPrivKeyRef->desc.type) {
558          case tls_private_key_type_rsa:
559              sigAlg.signature = tls_signature_algorithm_RSA;
560              break;
561          case tls_private_key_type_ecdsa:
562              sigAlg.signature = tls_signature_algorithm_ECDSA;
563              if (ctx->negProtocolVersion <= tls_protocol_version_SSL_3) {
564                  return errSSLInternal;
565              }
566  			break;
567  		default:
568  			/* shouldn't be here */
569  			assert(0);
570  			return errSSLInternal;
571  	}
572  
573  	assert(ctx->negProtocolVersion >= tls_protocol_version_SSL_3);
574      head = SSLHandshakeHeaderSize(ctx);
575  
576      outputLen = maxSigLen + head + 2;
577  
578      // Note: this is only used for TLS 1.2
579      if (sslVersionIsLikeTls12(ctx)) {
580          err=FindCertSigAlg(ctx, &sigAlg);
581          if(err)
582              goto fail;
583          outputLen += 2;
584          ctx->certSigAlg = sigAlg; // Save for metrics reporting.
585      }
586  
587      assert(ctx->sslTslCalls != NULL);
588      if ((err = ctx->sslTslCalls->computeCertVfyMac(ctx, &hashDataBuf, sigAlg.hash)) != 0)
589          goto fail;
590  
591      if ((err = SSLAllocBuffer(certVerify, outputLen)) != 0)
592          goto fail;
593  
594      /* Sign now to get the actual length */
595      charPtr = certVerify->data+head;
596  
597      if (sslVersionIsLikeTls12(ctx))
598      {
599          *charPtr++ = sigAlg.hash;
600          *charPtr++ = sigAlg.signature;
601  
602          switch (sigAlg.hash) {
603              case tls_hash_algorithm_SHA512:
604              case tls_hash_algorithm_SHA384:
605              case tls_hash_algorithm_SHA256:
606              case tls_hash_algorithm_SHA1:
607                  break;
608              default:
609  				sslErrorLog("SSLEncodeCertificateVerify: unsupported signature hash algorithm (%d)\n",
610  					sigAlg.hash);
611                  assert(0);          // if you get here, something is wrong in FindCertSigAlg
612                  err=errSSLInternal;
613                  goto fail;
614          }
615  
616          if (sigAlg.signature == tls_signature_algorithm_RSA) {
617              err = sslRsaSign(ctx->signingPrivKeyRef,
618                               sigAlg.hash,
619                               hashData,
620                               hashDataBuf.length,
621                               charPtr+2,
622                               maxSigLen,
623                               &outputLen);
624          } else {
625              err = sslEcdsaSign(ctx->signingPrivKeyRef,
626                               hashData,
627                               hashDataBuf.length,
628                               charPtr+2,
629                               maxSigLen,
630                               &outputLen);
631          }
632          len=outputLen+2+2;
633      } else {
634          err = sslRawSign(ctx->signingPrivKeyRef,
635              hashData,						// data to sign
636              hashDataBuf.length,				// Data to sign size
637              charPtr+2,	// signature destination
638              maxSigLen,							// we mallocd len+head+2
639              &outputLen);
640          len = outputLen+2;
641      }
642  	if(err) {
643  		sslErrorLog("SSLEncodeCertificateVerify: unable to sign data (error %d)\n", (int)err);
644  		goto fail;
645  	}
646      // At this point:
647      //  len = message length
648      //  outputlen = sig length
649  	certVerify->length = len + head;
650  
651      /* charPtr point at the len field here */
652      SSLEncodeSize(charPtr, outputLen, 2);
653  
654      SSLEncodeHandshakeHeader(ctx, certVerify, SSL_HdskCertVerify, len);
655  
656      err = errSSLSuccess;
657  
658  fail:
659  
660      return err;
661  }
662  
663  int
664  SSLProcessCertificateVerify(tls_buffer message, tls_handshake_t ctx)
665  {   int        err;
666      UInt8           hashData[SSL_MAX_DIGEST_LEN];
667      size_t          signatureLen;
668      tls_buffer       hashDataBuf;
669      uint8_t         *charPtr = message.data;
670  	uint8_t         *endCp = charPtr + message.length;
671  
672      tls_signature_and_hash_algorithm    sigAlg = {0,};
673  
674      if (sslVersionIsLikeTls12(ctx)) {
675          /* Parse the algorithm field added in TLS1.2 */
676          if((charPtr+2) > endCp) {
677              sslErrorLog("SSLProcessCertificateVerify: msg len error 1\n");
678              return errSSLProtocol;
679          }
680          sigAlg.hash = *charPtr++;
681          sigAlg.signature = *charPtr++;
682      }
683  
684      if ((charPtr + 2) > endCp) {
685      	sslErrorLog("SSLProcessCertificateVerify: msg len error\n");
686          return errSSLProtocol;
687      }
688  
689      signatureLen = SSLDecodeSize(charPtr, 2);
690      charPtr += 2;
691      if ((charPtr + signatureLen) > endCp) {
692      	sslErrorLog("SSLProcessCertificateVerify: sig len error 1\n");
693          return errSSLProtocol;
694      }
695  
696      hashDataBuf.data = hashData;
697      hashDataBuf.length = SSL_MAX_DIGEST_LEN;
698  
699  	assert(ctx->sslTslCalls != NULL);
700      if ((err = ctx->sslTslCalls->computeCertVfyMac(ctx, &hashDataBuf, sigAlg.hash)) != 0)
701          goto fail;
702  
703      if (sslVersionIsLikeTls12(ctx))
704      {
705          if(sigAlg.signature==tls_signature_algorithm_RSA) {
706              err = sslRsaVerify(&ctx->peerPubKey,
707                                 sigAlg.hash,
708                                 hashData,
709                                 hashDataBuf.length,
710                                 charPtr,
711                                 signatureLen);
712          } else {
713              err = sslRawVerify(&ctx->peerPubKey,
714                                 hashData,
715                                 hashDataBuf.length,
716                                 charPtr,
717                                 signatureLen);
718          }
719      } else {
720          /* sslRawVerify does the decrypt & compare for us in one shot. */
721          err = sslRawVerify(&ctx->peerPubKey,
722              hashData,				// data to verify
723              hashDataBuf.length,
724              charPtr, 		// signature
725              signatureLen);
726      }
727  
728      if(err) {
729  		SSLFatalSessionAlert(SSL_AlertDecryptError, ctx);
730  		goto fail;
731  	}
732      err = errSSLSuccess;
733  
734  fail:
735      return err;
736  }