Index: net/third_party/nss/ssl/ssl.h =================================================================== --- net/third_party/nss/ssl/ssl.h (revision 225295) +++ net/third_party/nss/ssl/ssl.h (working copy) @@ -434,6 +434,15 @@ */ SSL_IMPORT CERTCertificate *SSL_PeerCertificate(PRFileDesc *fd); +/* +** Return the certificates presented by the SSL peer. If the SSL peer +** did not present certificates, return NULL with the +** SSL_ERROR_NO_CERTIFICATE error. On failure, return NULL with an error +** code other than SSL_ERROR_NO_CERTIFICATE. +** "fd" the socket "file" descriptor +*/ +SSL_IMPORT CERTCertList *SSL_PeerCertificateChain(PRFileDesc *fd); + /* SSL_PeerStapledOCSPResponses returns the OCSP responses that were provided * by the TLS server. The return value is a pointer to an internal SECItemArray * that contains the returned OCSP responses; it is only valid until the @@ -463,18 +472,6 @@ SSLKEAType kea); /* -** Return references to the certificates presented by the SSL peer. -** |maxNumCerts| must contain the size of the |certs| array. On successful -** return, |*numCerts| contains the number of certificates available and -** |certs| will contain references to as many certificates as would fit. -** Therefore if |*numCerts| contains a value less than or equal to -** |maxNumCerts|, then all certificates were returned. -*/ -SSL_IMPORT SECStatus SSL_PeerCertificateChain( - PRFileDesc *fd, CERTCertificate **certs, - unsigned int *numCerts, unsigned int maxNumCerts); - -/* ** Authenticate certificate hook. Called when a certificate comes in ** (because of SSL_REQUIRE_CERTIFICATE in SSL_Enable) to authenticate the ** certificate. Index: net/third_party/nss/ssl/sslauth.c =================================================================== --- net/third_party/nss/ssl/sslauth.c (revision 225295) +++ net/third_party/nss/ssl/sslauth.c (working copy) @@ -28,38 +28,43 @@ } /* NEED LOCKS IN HERE. */ -SECStatus -SSL_PeerCertificateChain(PRFileDesc *fd, CERTCertificate **certs, - unsigned int *numCerts, unsigned int maxNumCerts) +CERTCertList * +SSL_PeerCertificateChain(PRFileDesc *fd) { sslSocket *ss; - ssl3CertNode* cur; + CERTCertList *chain = NULL; + CERTCertificate *cert; + ssl3CertNode *cur; ss = ssl_FindSocket(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificateChain", SSL_GETPID(), fd)); - return SECFailure; + return NULL; } - if (!ss->opt.useSecurity) - return SECFailure; - - if (ss->sec.peerCert == NULL) { - *numCerts = 0; - return SECSuccess; + if (!ss->opt.useSecurity || !ss->sec.peerCert) { + PORT_SetError(SSL_ERROR_NO_CERTIFICATE); + return NULL; } - - *numCerts = 1; /* for the leaf certificate */ - if (maxNumCerts > 0) - certs[0] = CERT_DupCertificate(ss->sec.peerCert); - + chain = CERT_NewCertList(); + if (!chain) { + return NULL; + } + cert = CERT_DupCertificate(ss->sec.peerCert); + if (CERT_AddCertToListTail(chain, cert) != SECSuccess) { + goto loser; + } for (cur = ss->ssl3.peerCertChain; cur; cur = cur->next) { - if (*numCerts < maxNumCerts) - certs[*numCerts] = CERT_DupCertificate(cur->cert); - (*numCerts)++; + cert = CERT_DupCertificate(cur->cert); + if (CERT_AddCertToListTail(chain, cert) != SECSuccess) { + goto loser; + } } + return chain; - return SECSuccess; +loser: + CERT_DestroyCertList(chain); + return NULL; } /* NEED LOCKS IN HERE. */