[xmlsec] cleanup pkcs12



commit 68b608ba3ee5571330d82c0c9b2cd60b7c468b59
Author: Aleksey Sanin <aleksey aleksey com>
Date:   Mon May 24 09:45:35 2010 -0700

    cleanup pkcs12

 src/gnutls/app.c       |  135 +++++++++++++++++------------------------------
 src/gnutls/asymkeys.c  |  136 +++++++++++++++++++++++++++++++++++++++++++-----
 src/gnutls/x509utils.c |   70 +++++++++++++++++++++++++
 src/gnutls/x509utils.h |    1 +
 src/gnutls/x509vfy.c   |   43 ++++++++++++---
 5 files changed, 276 insertions(+), 109 deletions(-)
---
diff --git a/src/gnutls/app.c b/src/gnutls/app.c
index 18afb37..e510cee 100644
--- a/src/gnutls/app.c
+++ b/src/gnutls/app.c
@@ -359,7 +359,7 @@ xmlSecGnuTLSAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
     xmlSecKeyDataPtr keyData = NULL;
     xmlSecKeyDataPtr x509Data = NULL;
     gnutls_x509_privkey_t priv_key = NULL;
-    gnutls_x509_crt_t cert = NULL;
+    gnutls_x509_crt_t key_cert = NULL;
     xmlSecSize certsSize;
     int err;
     int ret;
@@ -378,6 +378,18 @@ xmlSecGnuTLSAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
         return(NULL);
     }
 
+    /* load pkcs12 */
+    ret = xmlSecGnuTLSPkcs12LoadMemory(data, dataSize, pwd, &priv_key, &key_cert, &certsList);
+    if((ret < 0) || (priv_key == NULL)) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "xmlSecGnuTLSPkcs12LoadMemory",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    XMLSEC_ERRORS_NO_MESSAGE);
+        goto done;
+    }
+
+    /* create key */
     key = xmlSecKeyCreate();
     if(key == NULL) {
         xmlSecError(XMLSEC_ERRORS_HERE,
@@ -388,24 +400,34 @@ xmlSecGnuTLSAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
         goto done;
     }
 
-    /* load pkcs12 */
-    ret = xmlSecGnuTLSPkcs12LoadMemory(data, dataSize, pwd, &priv_key, &certsList);
-    if((ret < 0) || (priv_key == NULL)) {
+    /* create key value data */
+    keyData = xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey(priv_key);
+    if(keyData == NULL) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     NULL,
-                    "xmlSecGnuTLSPkcs12LoadMemory",
+                    "xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey",
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
                     XMLSEC_ERRORS_NO_MESSAGE);
         goto done;
     }
+    priv_key = NULL; /* owned by keyData now */
+
+    ret = xmlSecKeySetValue(key, keyData);
+    if(ret < 0) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "xmlSecKeySetValue",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    "data=%s",
+                    xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
+        goto done;
+    }
+    keyData = NULL; /* owned by key now */
+
 
     /* create x509 certs data */
     certsSize = xmlSecPtrListGetSize(&certsList);
-    if(certsSize > 0) {
-        size_t cert_id_size = 0;
-        size_t key_id_size = 0;
-        xmlSecByte cert_id[100];
-        xmlSecByte key_id[100];
+    if((certsSize > 0) || (key_cert != NULL)) {
         xmlSecSize ii;
 
         x509Data = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataX509Id);
@@ -418,59 +440,25 @@ xmlSecGnuTLSAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
             goto done;
         }
 
-        /* we will search for cert for this key using the key id */
-        key_id_size = sizeof(key_id);
-        err = gnutls_x509_privkey_get_key_id(priv_key, 0, key_id, &key_id_size);
-        if(err != GNUTLS_E_SUCCESS) {
-            xmlSecError(XMLSEC_ERRORS_HERE,
-                        NULL,
-                        "gnutls_x509_privkey_get_key_id",
-                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                        XMLSEC_GNUTLS_REPORT_ERROR(err));
-            goto done;
-        }
-        for(ii = 0; ii < certsSize; ++ii) {
-            cert = xmlSecPtrListRemoveAndReturn(&certsList, ii);
-            if(cert == NULL) {
-                continue;
-            }
-
-            cert_id_size = sizeof(cert_id);
-            err = gnutls_x509_crt_get_key_id(cert, 0, cert_id, &cert_id_size);
-            if(err != GNUTLS_E_SUCCESS) {
+        /* set key's cert */
+        if(key_cert != NULL) {
+            ret = xmlSecGnuTLSKeyDataX509AdoptKeyCert(x509Data, key_cert);
+            if(ret < 0) {
                 xmlSecError(XMLSEC_ERRORS_HERE,
                             NULL,
-                            "gnutls_x509_crt_get_key_id",
-                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                            XMLSEC_GNUTLS_REPORT_ERROR(err));
+                            "xmlSecGnuTLSKeyDataX509AdoptKeyCert",
+                            XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                            XMLSEC_ERRORS_NO_MESSAGE);
                 goto done;
             }
+            key_cert = NULL; /* owned by x509Data now */
+        }
 
-            /* if key ids match, then this is THE key cert!!! */
-            if((key_id_size == cert_id_size) && (memcmp(key_id, cert_id, key_id_size) == 0)) {
-                gnutls_x509_crt_t tmpCert;
-
-                tmpCert = xmlSecGnuTLSX509CertDup(cert);
-                if(tmpCert == NULL) {
-                    xmlSecError(XMLSEC_ERRORS_HERE,
-                                NULL,
-                                "xmlSecGnuTLSX509CertDup",
-                                XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                                XMLSEC_ERRORS_NO_MESSAGE);
-                    goto done;
-                }
-
-                ret = xmlSecGnuTLSKeyDataX509AdoptKeyCert(x509Data, tmpCert);
-                if(ret < 0) {
-                    xmlSecError(XMLSEC_ERRORS_HERE,
-                                NULL,
-                                "xmlSecGnuTLSKeyDataX509AdoptKeyCert",
-                                XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                                XMLSEC_ERRORS_NO_MESSAGE);
-                    gnutls_x509_crt_deinit(tmpCert);
-                    goto done;
-                }
-                tmpCert = NULL; /* owned by x509Data now */
+        /* copy all other certs */
+        for(ii = 0; ii < certsSize; ++ii) {
+            gnutls_x509_crt_t cert = xmlSecPtrListRemoveAndReturn(&certsList, ii);
+            if(cert == NULL) {
+                continue;
             }
 
             ret = xmlSecGnuTLSKeyDataX509AdoptCert(x509Data, cert);
@@ -480,9 +468,9 @@ xmlSecGnuTLSAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
                             "xmlSecGnuTLSKeyDataX509AdoptCert",
                             XMLSEC_ERRORS_R_XMLSEC_FAILED,
                             XMLSEC_ERRORS_NO_MESSAGE);
+                gnutls_x509_crt_deinit(cert);
                 goto done;
             }
-            cert = NULL; /* owned by x509Data now */
         }
 
         /* set in the key */
@@ -499,38 +487,13 @@ xmlSecGnuTLSAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
         x509Data = NULL; /* owned by key now */
     }
 
-
-    /* create key value data */
-    keyData = xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey(priv_key);
-    if(keyData == NULL) {
-        xmlSecError(XMLSEC_ERRORS_HERE,
-                    NULL,
-                    "xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey",
-                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                    XMLSEC_ERRORS_NO_MESSAGE);
-        goto done;
-    }
-    priv_key = NULL; /* owned by keyData now */
-
-    ret = xmlSecKeySetValue(key, keyData);
-    if(ret < 0) {
-        xmlSecError(XMLSEC_ERRORS_HERE,
-                    NULL,
-                    "xmlSecKeySetValue",
-                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                    "data=%s",
-                    xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
-        goto done;
-    }
-    keyData = NULL; /* owned by key now */
-
     /* success!!! */
     res = key;
     key = NULL;
 
 done:
-    if(cert != NULL) {
-        gnutls_x509_crt_deinit(cert);
+    if(key_cert != NULL) {
+        gnutls_x509_crt_deinit(key_cert);
     }
     if(priv_key != NULL) {
         gnutls_x509_privkey_deinit(priv_key);
diff --git a/src/gnutls/asymkeys.c b/src/gnutls/asymkeys.c
index e1f7f00..6ac68a7 100644
--- a/src/gnutls/asymkeys.c
+++ b/src/gnutls/asymkeys.c
@@ -53,20 +53,20 @@ static int xmlSecGnuTLSConvertParamsToMpis(gnutls_datum_t * params, xmlSecSize p
                                            gcry_mpi_t * mpis, xmlSecSize mpisNum) {
 
     xmlSecSize ii;
-    int err;
+    int rc;
 
     xmlSecAssert2(params != NULL, -1);
     xmlSecAssert2(mpis != NULL, -1);
     xmlSecAssert2(paramsNum == mpisNum, -1);
 
     for(ii = 0; ii < paramsNum; ++ii) {
-        err = gcry_mpi_scan(&(mpis[ii]), GCRYMPI_FMT_USG, params[ii].data, params[ii].size, NULL);
-        if((err != GPG_ERR_NO_ERROR) || (mpis[ii] == NULL)) {
+        rc = gcry_mpi_scan(&(mpis[ii]), GCRYMPI_FMT_USG, params[ii].data, params[ii].size, NULL);
+        if((rc != GPG_ERR_NO_ERROR) || (mpis[ii] == NULL)) {
             xmlSecError(XMLSEC_ERRORS_HERE,
                         NULL,
                         "gcry_mpi_scan",
                         XMLSEC_ERRORS_R_CRYPTO_FAILED,
-                        XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(err));
+                        XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc));
             xmlSecGnuTLSDestroyMpis(mpis, ii); /* destroy up to now */
             return(-1);
         }
@@ -144,23 +144,23 @@ xmlSecGnuTLSKeyDataDsaAdoptPrivateKey(xmlSecKeyDataPtr data, gnutls_x509_privkey
     /* build expressions */
     rc = gcry_sexp_build(&(priv_key), NULL, "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
                         mpis[0], mpis[1], mpis[2], mpis[3], mpis[4]);
-    if((err != GPG_ERR_NO_ERROR) || (priv_key == NULL)) {
+    if((rc != GPG_ERR_NO_ERROR) || (priv_key == NULL)) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     NULL,
                     "gcry_sexp_build(private/dsa)",
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                    XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(err));
+                    XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc));
         xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
         return(-1);
     }
     rc = gcry_sexp_build(&(pub_key), NULL, "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
                         mpis[0], mpis[1], mpis[2], mpis[3]);
-    if((err != GPG_ERR_NO_ERROR) || (priv_key == NULL)) {
+    if((rc != GPG_ERR_NO_ERROR) || (pub_key == NULL)) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     NULL,
                     "gcry_sexp_build(private/rsa)",
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                    XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(err));
+                    XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc));
         gcry_sexp_release(priv_key);
         xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
         return(-1);
@@ -201,13 +201,69 @@ int
 xmlSecGnuTLSKeyDataDsaAdoptPublicKey(xmlSecKeyDataPtr data,
                                      gnutls_datum_t * p, gnutls_datum_t * q,
                                      gnutls_datum_t * g, gnutls_datum_t * y) {
+    gnutls_datum_t params[4];
+    gcry_mpi_t mpis[4];
+    gcry_sexp_t pub_key = NULL;
+    int rc;
+    int ret;
+
     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), -1);
     xmlSecAssert2(p != NULL, -1);
     xmlSecAssert2(q != NULL, -1);
     xmlSecAssert2(g != NULL, -1);
     xmlSecAssert2(y != NULL, -1);
 
-    /* ALEKSEY_TODO */
+    /* copy */
+    memcpy(&(params[0]), p, sizeof(*p));
+    memcpy(&(params[1]), q, sizeof(*q));
+    memcpy(&(params[2]), g, sizeof(*g));
+    memcpy(&(params[3]), y, sizeof(*y));
+
+    /* convert to mpis */
+    ret = xmlSecGnuTLSConvertParamsToMpis(
+            params, sizeof(params)/sizeof(params[0]),
+            mpis, sizeof(mpis)/sizeof(mpis[0]));
+    if(ret < 0) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "xmlSecGnuTLSConvertParamsToMpis",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    XMLSEC_ERRORS_NO_MESSAGE);
+        /* don't destroy params - we got them from outside !!! */
+        return(-1);
+    }
+    /* don't destroy params - we got them from outside !!! */
+
+    /* build expressions */
+    rc = gcry_sexp_build(&(pub_key), NULL, "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
+                        mpis[0], mpis[1], mpis[2], mpis[3]);
+    if((rc != GPG_ERR_NO_ERROR) || (pub_key == NULL)) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "gcry_sexp_build(private/rsa)",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc));
+        xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+        return(-1);
+    }
+    xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+
+    ret = xmlSecGCryptKeyDataDsaAdoptKeyPair(data, pub_key, NULL);
+    if(ret < 0) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "xmlSecGCryptKeyDataDsaAdoptKeyPair",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    XMLSEC_ERRORS_NO_MESSAGE);
+        gcry_sexp_release(pub_key);
+        return(-1);
+    }
+
+    /* done, we "adopted" the key - destroy it! */
+    gnutls_free(p->data);
+    gnutls_free(q->data);
+    gnutls_free(g->data);
+    gnutls_free(y->data);
     return(0);
 }
 
@@ -283,23 +339,23 @@ xmlSecGnuTLSKeyDataRsaAdoptPrivateKey(xmlSecKeyDataPtr data, gnutls_x509_privkey
     rc = gcry_sexp_build(&(priv_key), NULL, "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))",
                         mpis[0], mpis[1], mpis[2],
                         mpis[3], mpis[4], mpis[5]);
-    if((err != GPG_ERR_NO_ERROR) || (priv_key == NULL)) {
+    if((rc != GPG_ERR_NO_ERROR) || (priv_key == NULL)) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     NULL,
                     "gcry_sexp_build(private/rsa)",
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                    XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(err));
+                    XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc));
         xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
         return(-1);
     }
     rc = gcry_sexp_build(&(pub_key), NULL, "(public-key(rsa((n%m)(e%m))))",
                         mpis[0], mpis[1]);
-    if((err != GPG_ERR_NO_ERROR) || (priv_key == NULL)) {
+    if((rc != GPG_ERR_NO_ERROR) || (pub_key == NULL)) {
         xmlSecError(XMLSEC_ERRORS_HERE,
                     NULL,
                     "gcry_sexp_build(private/rsa)",
                     XMLSEC_ERRORS_R_XMLSEC_FAILED,
-                    XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(err));
+                    XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc));
         gcry_sexp_release(priv_key);
         xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
         return(-1);
@@ -337,11 +393,63 @@ xmlSecGnuTLSKeyDataRsaAdoptPrivateKey(xmlSecKeyDataPtr data, gnutls_x509_privkey
 int
 xmlSecGnuTLSKeyDataRsaAdoptPublicKey(xmlSecKeyDataPtr data,
                                      gnutls_datum_t * m, gnutls_datum_t * e) {
+    gnutls_datum_t params[2];
+    gcry_mpi_t mpis[2];
+    gcry_sexp_t pub_key = NULL;
+    int rc;
+    int ret;
+
     xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), -1);
     xmlSecAssert2(m != NULL, -1);
     xmlSecAssert2(e != NULL, -1);
 
-    /* ALEKSEY_TODO */
+    /* copy */
+    memcpy(&(params[0]), m, sizeof(*m));
+    memcpy(&(params[1]), e, sizeof(*e));
+
+    /* convert to mpis */
+    ret = xmlSecGnuTLSConvertParamsToMpis(
+            params, sizeof(params)/sizeof(params[0]),
+            mpis, sizeof(mpis)/sizeof(mpis[0]));
+    if(ret < 0) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "xmlSecGnuTLSConvertParamsToMpis",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    XMLSEC_ERRORS_NO_MESSAGE);
+        /* don't destroy params - we got them from outside !!! */
+        return(-1);
+    }
+    /* don't destroy params - we got them from outside !!! */
+
+    /* build expressions */
+    rc = gcry_sexp_build(&(pub_key), NULL, "(public-key(rsa((n%m)(e%m))))",
+                        mpis[0], mpis[1]);
+    if((rc != GPG_ERR_NO_ERROR) || (pub_key == NULL)) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "gcry_sexp_build(private/rsa)",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(rc));
+        xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+        return(-1);
+    }
+    xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+
+    ret = xmlSecGCryptKeyDataRsaAdoptKeyPair(data, pub_key, NULL);
+    if(ret < 0) {
+        xmlSecError(XMLSEC_ERRORS_HERE,
+                    NULL,
+                    "xmlSecGCryptKeyDataRsaAdoptKeyPair",
+                    XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                    XMLSEC_ERRORS_NO_MESSAGE);
+        gcry_sexp_release(pub_key);
+        return(-1);
+    }
+
+    /* done, we "adopted" the key - destroy it! */
+    gnutls_free(m->data);
+    gnutls_free(e->data);
     return(0);
 }
 #endif /* XMLSEC_NO_RSA */
diff --git a/src/gnutls/x509utils.c b/src/gnutls/x509utils.c
index 14c292f..037096f 100644
--- a/src/gnutls/x509utils.c
+++ b/src/gnutls/x509utils.c
@@ -387,9 +387,11 @@ xmlSecGnuTLSX509CertRead(const xmlSecByte* buf, xmlSecSize size, xmlSecKeyDataFo
 
     /* figure out format */
     switch(format) {
+    case xmlSecKeyDataFormatPem:
     case xmlSecKeyDataFormatCertPem:
         fmt = GNUTLS_X509_FMT_PEM;
         break;
+    case xmlSecKeyDataFormatDer:
     case xmlSecKeyDataFormatCertDer:
         fmt = GNUTLS_X509_FMT_DER;
         break;
@@ -592,12 +594,14 @@ int
 xmlSecGnuTLSPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
                              const char *pwd,
                              gnutls_x509_privkey_t * priv_key,
+                             gnutls_x509_crt_t * key_cert,
                              xmlSecPtrListPtr certsList)
 {
     gnutls_pkcs12_t pkcs12 = NULL;
     gnutls_pkcs12_bag_t bag = NULL;
     gnutls_x509_crt_t cert = NULL;
     gnutls_datum_t datum;
+    xmlSecSize certsSize;
     int res = -1;
     int idx;
     int err;
@@ -607,6 +611,8 @@ xmlSecGnuTLSPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
     xmlSecAssert2(dataSize > 0, -1);
     xmlSecAssert2(priv_key != NULL, -1);
     xmlSecAssert2((*priv_key) == NULL, -1);
+    xmlSecAssert2(key_cert!= NULL, -1);
+    xmlSecAssert2((*key_cert) == NULL, -1);
     xmlSecAssert2(certsList != NULL, -1);
 
     /* read pkcs12 in internal structure */
@@ -807,6 +813,70 @@ xmlSecGnuTLSPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
         goto done;
     }
 
+    /* we will search for key cert using the key id */
+    certsSize = xmlSecPtrListGetSize(certsList);
+    if(certsSize > 0) {
+        size_t cert_id_size = 0;
+        size_t key_id_size = 0;
+        xmlSecByte cert_id[100];
+        xmlSecByte key_id[100];
+        xmlSecSize ii;
+
+        key_id_size = sizeof(key_id);
+        err = gnutls_x509_privkey_get_key_id((*priv_key), 0, key_id, &key_id_size);
+        if(err != GNUTLS_E_SUCCESS) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        "gnutls_x509_privkey_get_key_id",
+                        XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                        XMLSEC_GNUTLS_REPORT_ERROR(err));
+            goto done;
+        }
+        for(ii = 0; ii < certsSize; ++ii) {
+            cert = xmlSecPtrListRemoveAndReturn(certsList, ii);
+            if(cert == NULL) {
+                continue;
+            }
+
+            cert_id_size = sizeof(cert_id);
+            err = gnutls_x509_crt_get_key_id(cert, 0, cert_id, &cert_id_size);
+            if(err != GNUTLS_E_SUCCESS) {
+                xmlSecError(XMLSEC_ERRORS_HERE,
+                            NULL,
+                            "gnutls_x509_crt_get_key_id",
+                            XMLSEC_ERRORS_R_CRYPTO_FAILED,
+                            XMLSEC_GNUTLS_REPORT_ERROR(err));
+                goto done;
+            }
+
+            /* if key ids match, then this is THE key cert!!! */
+            if((key_id_size == cert_id_size) && (memcmp(key_id, cert_id, key_id_size) == 0)) {
+                (*key_cert) = xmlSecGnuTLSX509CertDup(cert);
+                if((*key_cert) == NULL) {
+                    xmlSecError(XMLSEC_ERRORS_HERE,
+                                NULL,
+                                "xmlSecGnuTLSX509CertDup",
+                                XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                                XMLSEC_ERRORS_NO_MESSAGE);
+                    goto done;
+                }
+
+                break;
+            }
+        }
+
+        /* check we have key cert */
+        if((*key_cert) == NULL) {
+            xmlSecError(XMLSEC_ERRORS_HERE,
+                        NULL,
+                        NULL,
+                        XMLSEC_ERRORS_R_XMLSEC_FAILED,
+                        "Certificate for the private key was not found in pkcs12 object");
+            goto done;
+        }
+    }
+
+
     /* success!!! */
     res = 0;
 
diff --git a/src/gnutls/x509utils.h b/src/gnutls/x509utils.h
index da5325c..33bb3eb 100644
--- a/src/gnutls/x509utils.h
+++ b/src/gnutls/x509utils.h
@@ -66,6 +66,7 @@ int                     xmlSecGnuTLSPkcs12LoadMemory            (const xmlSecByt
                                                                  xmlSecSize dataSize,
                                                                  const char *pwd,
                                                                  gnutls_x509_privkey_t * priv_key,
+                                                                 gnutls_x509_crt_t * key_cert,
                                                                  xmlSecPtrListPtr certsList);
 
 xmlSecKeyDataPtr        xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey(gnutls_x509_privkey_t priv_key);
diff --git a/src/gnutls/x509vfy.c b/src/gnutls/x509vfy.c
index e4bb7d1..0ebbcb0 100644
--- a/src/gnutls/x509vfy.c
+++ b/src/gnutls/x509vfy.c
@@ -149,10 +149,43 @@ gnutls_x509_crt_t
 xmlSecGnuTLSX509StoreVerify(xmlSecKeyDataStorePtr store,
                             xmlSecPtrListPtr certs,
                             const xmlSecKeyInfoCtx* keyInfoCtx) {
+    xmlSecGnuTLSX509StoreCtxPtr ctx;
+
+    xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecGnuTLSX509StoreId), NULL);
+    xmlSecAssert2(certs != NULL, NULL);
+    xmlSecAssert2(keyInfoCtx != NULL, NULL);
+
+    ctx = xmlSecGnuTLSX509StoreGetCtx(store);
+    xmlSecAssert2(ctx != NULL, NULL);
+
+    /* We are going to build all possible cert chains and try to verify them */
+
+    /*
+    for(ii = 0; ii < certs.size; ++ii) {
+        cert = certs[ii];
+        if(find(certs, where issuer = cert.subj)) {
+            continue; // this is not the "leaf" of a certs chain!
+        }
+        // build chain
+        for(cert2 = cert; ; ) {
+            put cert2 into certsChain;
+            cert2 = find(certs, where subject = cert2.issuer);
+            if(cert2 == NULL) {
+                cert2 = find(untrusted certs from store, where subject = cert2.issuer);
+            }
+        }
+        if(gnutls_x509_crt_list_verify(certsChain, trusted certs from store)) {
+            // we found it!
+            cert is the key cert;
+
+            // manually check certs time if specified 
+        }
+    }
+    */
+
     return(NULL);
 
 #ifdef TODO
-    xmlSecGnuTLSX509StoreCtxPtr ctx;
     STACK_OF(X509)* certs2 = NULL;
     X509 * res = NULL;
     X509 * cert;
@@ -162,14 +195,6 @@ xmlSecGnuTLSX509StoreVerify(xmlSecKeyDataStorePtr store,
     int i;
     int ret;
 
-    xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecGnuTLSX509StoreId), NULL);
-    xmlSecAssert2(certs != NULL, NULL);
-    xmlSecAssert2(keyInfoCtx != NULL, NULL);
-
-    ctx = xmlSecGnuTLSX509StoreGetCtx(store);
-    xmlSecAssert2(ctx != NULL, NULL);
-    xmlSecAssert2(ctx->xst != NULL, NULL);
-
     /* dup certs */
     certs2 = sk_X509_dup(certs);
     if(certs2 == NULL) {



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