[xmlsec] ensure we have only one copy of key's cert after reading pkcs12 from openssl



commit 82f7d47f1cd40edde4b33598037be9f4f6617026
Author: Aleksey Sanin <aleksey aleksey com>
Date:   Thu Mar 18 18:28:45 2010 -0700

    ensure we have only one copy of key's cert after reading pkcs12 from openssl

 src/openssl/app.c |   68 +++++++++++++++++++++++++++++++++++------------------
 1 files changed, 45 insertions(+), 23 deletions(-)
---
diff --git a/src/openssl/app.c b/src/openssl/app.c
index 88dbc09..67a2f48 100644
--- a/src/openssl/app.c
+++ b/src/openssl/app.c
@@ -663,6 +663,7 @@ xmlSecOpenSSLAppPkcs12LoadBIO(BIO* bio, const char *pwd,
     X509 *cert = NULL;
     X509 *tmpcert = NULL;
     int i;
+	int has_cert;
     int ret;
 
     xmlSecAssert2(bio != NULL, NULL);
@@ -719,17 +720,6 @@ xmlSecOpenSSLAppPkcs12LoadBIO(BIO* bio, const char *pwd,
 	goto done;
     }    
 
-    tmpcert = X509_dup(cert);
-    if(tmpcert == NULL) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "X509_dup",
-		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    "data=%s",
-		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
-	goto done;	
-    }
-
     /* starting from openssl 1.0.0 the PKCS12_parse() call will not create certs 
        chain object if there is no certificates in the pkcs12 file and it will be null
      */
@@ -744,19 +734,51 @@ xmlSecOpenSSLAppPkcs12LoadBIO(BIO* bio, const char *pwd,
 	    goto done;
 	}    
     } 
-        
-    ret = sk_X509_push(chain, tmpcert);
-    if(ret < 1) {
-	xmlSecError(XMLSEC_ERRORS_HERE,
-		    NULL,
-		    "sk_X509_push",
-		    XMLSEC_ERRORS_R_CRYPTO_FAILED,
-		    "data=%s",
-		    xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
-	X509_free(tmpcert);
-	goto done;	
-    }
     
+	/*
+	The documentation states (http://www.openssl.org/docs/crypto/PKCS12_parse.html):
+
+	If successful the private key will be written to "*pkey", the
+    corresponding certificate to "*cert" and any additional certificates
+    to "*ca".
+
+	In reality, the function sometime returns in the "ca" the certificates
+    including the one it is already returned in "cert".
+	*/
+	has_cert = 0;
+    for(i = 0; i < sk_X509_num(chain); ++i) {
+		xmlSecAssert2(sk_X509_value(chain, i), NULL);
+
+		if(X509_cmp(sk_X509_value(chain, i), cert) == 0) {
+			has_cert = 1;
+			break;
+		}
+	}	
+	if(has_cert != 0) {
+		tmpcert = X509_dup(cert);
+		if(tmpcert == NULL) {
+		xmlSecError(XMLSEC_ERRORS_HERE,
+				NULL,
+				"X509_dup",
+				XMLSEC_ERRORS_R_CRYPTO_FAILED,
+				"data=%s",
+				xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
+		goto done;	
+		}
+
+		ret = sk_X509_push(chain, tmpcert);
+		if(ret < 1) {
+		xmlSecError(XMLSEC_ERRORS_HERE,
+				NULL,
+				"sk_X509_push",
+				XMLSEC_ERRORS_R_CRYPTO_FAILED,
+				"data=%s",
+				xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
+		X509_free(tmpcert);
+		goto done;	
+		}
+	}
+
     ret = xmlSecOpenSSLKeyDataX509AdoptKeyCert(x509Data, cert);
     if(ret < 0) {
 	xmlSecError(XMLSEC_ERRORS_HERE,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]