diff -pu a/nss/lib/ssl/sslauth.c b/nss/lib/ssl/sslauth.c --- a/nss/lib/ssl/sslauth.c 2013-07-31 12:07:10.974699609 -0700 +++ b/nss/lib/ssl/sslauth.c 2013-07-31 12:32:07.996451064 -0700 @@ -28,6 +28,41 @@ SSL_PeerCertificate(PRFileDesc *fd) } /* NEED LOCKS IN HERE. */ +SECStatus +SSL_PeerCertificateChain(PRFileDesc *fd, CERTCertificate **certs, + unsigned int *numCerts, unsigned int maxNumCerts) +{ + sslSocket *ss; + ssl3CertNode* cur; + + ss = ssl_FindSocket(fd); + if (!ss) { + SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificateChain", + SSL_GETPID(), fd)); + return SECFailure; + } + if (!ss->opt.useSecurity) + return SECFailure; + + if (ss->sec.peerCert == NULL) { + *numCerts = 0; + return SECSuccess; + } + + *numCerts = 1; /* for the leaf certificate */ + if (maxNumCerts > 0) + certs[0] = CERT_DupCertificate(ss->sec.peerCert); + + for (cur = ss->ssl3.peerCertChain; cur; cur = cur->next) { + if (*numCerts < maxNumCerts) + certs[*numCerts] = CERT_DupCertificate(cur->cert); + (*numCerts)++; + } + + return SECSuccess; +} + +/* NEED LOCKS IN HERE. */ CERTCertificate * SSL_LocalCertificate(PRFileDesc *fd) { diff -pu a/nss/lib/ssl/ssl.h b/nss/lib/ssl/ssl.h --- a/nss/lib/ssl/ssl.h 2013-07-31 12:07:10.964699464 -0700 +++ b/nss/lib/ssl/ssl.h 2013-07-31 12:32:07.996451065 -0700 @@ -426,6 +426,18 @@ SSL_SetStapledOCSPResponses(PRFileDesc * 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.