[xmlsec] added pkcs12 support for xmlsec-gnutls
- From: Aleksey Sanin <aleksey src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [xmlsec] added pkcs12 support for xmlsec-gnutls
- Date: Mon, 24 May 2010 22:36:03 +0000 (UTC)
commit c31c85a8aa19f571fcae601ced3dac0e73cf7101
Author: Aleksey Sanin <aleksey aleksey com>
Date: Sun May 23 23:05:11 2010 -0700
added pkcs12 support for xmlsec-gnutls
include/xmlsec/list.h | 2 +
src/gnutls/app.c | 299 ++++++++++++++++++++++++++++++++++++----
src/gnutls/asymkeys.c | 202 +++++++++++++++++++++++++++-
src/gnutls/x509.c | 8 +-
src/gnutls/x509utils.c | 357 +++++++++++++++++++++++++++++++++++++++++++++++-
src/gnutls/x509utils.h | 22 +++-
src/list.c | 26 ++++
src/openssl/app.c | 71 +++++-----
tests/testrun.sh | 2 +-
9 files changed, 912 insertions(+), 77 deletions(-)
---
diff --git a/include/xmlsec/list.h b/include/xmlsec/list.h
index e7900e7..fed9870 100644
--- a/include/xmlsec/list.h
+++ b/include/xmlsec/list.h
@@ -67,6 +67,8 @@ XMLSEC_EXPORT int xmlSecPtrListSet (xmlSecPtrListPt
xmlSecSize pos);
XMLSEC_EXPORT int xmlSecPtrListRemove (xmlSecPtrListPtr list,
xmlSecSize pos);
+XMLSEC_EXPORT xmlSecPtr xmlSecPtrListRemoveAndReturn (xmlSecPtrListPtr list,
+ xmlSecSize pos);
XMLSEC_EXPORT void xmlSecPtrListDebugDump (xmlSecPtrListPtr list,
FILE* output);
XMLSEC_EXPORT void xmlSecPtrListDebugXmlDump (xmlSecPtrListPtr list,
diff --git a/src/gnutls/app.c b/src/gnutls/app.c
index f01598b..18afb37 100644
--- a/src/gnutls/app.c
+++ b/src/gnutls/app.c
@@ -10,10 +10,6 @@
#include <string.h>
-#include <gnutls/gnutls.h>
-#include <gnutls/x509.h>
-#include <gnutls/pkcs12.h>
-
#include <xmlsec/xmlsec.h>
#include <xmlsec/keys.h>
#include <xmlsec/transforms.h>
@@ -21,6 +17,9 @@
#include <xmlsec/gnutls/app.h>
#include <xmlsec/gnutls/crypto.h>
+#include <xmlsec/gnutls/x509.h>
+
+#include "x509utils.h"
/**************************************************************************
*
@@ -225,18 +224,47 @@ xmlSecGnuTLSAppKeyCertLoadMemory(xmlSecKeyPtr key,
const xmlSecByte* data,
xmlSecSize dataSize,
xmlSecKeyDataFormat format) {
+ gnutls_x509_crt_t cert;
+ xmlSecKeyDataPtr keyData;
+ int ret;
+
xmlSecAssert2(key != NULL, -1);
xmlSecAssert2(data != NULL, -1);
xmlSecAssert2(dataSize > 0, -1);
xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
- /* TODO */
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlSecGnuTLSAppKeyCertLoadMemory",
- XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
+ keyData = xmlSecKeyEnsureData(key, xmlSecGnuTLSKeyDataX509Id);
+ if(keyData == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyEnsureData",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ cert = xmlSecGnuTLSX509CertRead(data, dataSize, format);
+ if(cert == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSKeyDataX509AdoptCert(keyData, cert);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSKeyDataX509AdoptCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gnutls_x509_crt_deinit(cert);
+ return(-1);
+ }
+
+ return(0);
}
/**
@@ -321,19 +349,203 @@ xmlSecGnuTLSAppPkcs12Load(const char *filename,
*/
xmlSecKeyPtr
xmlSecGnuTLSAppPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
- const char *pwd ATTRIBUTE_UNUSED,
- void* pwdCallback ATTRIBUTE_UNUSED,
- void* pwdCallbackCtx ATTRIBUTE_UNUSED) {
+ const char *pwd,
+ void* pwdCallback ATTRIBUTE_UNUSED,
+ void* pwdCallbackCtx ATTRIBUTE_UNUSED)
+{
+ xmlSecKeyPtr key = NULL;
+ xmlSecKeyPtr res = NULL;
+ xmlSecPtrList certsList;
+ xmlSecKeyDataPtr keyData = NULL;
+ xmlSecKeyDataPtr x509Data = NULL;
+ gnutls_x509_privkey_t priv_key = NULL;
+ gnutls_x509_crt_t cert = NULL;
+ xmlSecSize certsSize;
+ int err;
+ int ret;
+
xmlSecAssert2(data != NULL, NULL);
xmlSecAssert2(dataSize > 0, NULL);
- /* TODO */
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlSecGnuTLSAppPkcs12LoadMemory",
- XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(NULL);
+ /* prepare */
+ ret = xmlSecPtrListInitialize(&(certsList), xmlSecGnuTLSX509CrtListId);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListInitialize",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "certsList");
+ return(NULL);
+ }
+
+ key = xmlSecKeyCreate();
+ if(key == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+
+ /* load pkcs12 */
+ ret = xmlSecGnuTLSPkcs12LoadMemory(data, dataSize, pwd, &priv_key, &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 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];
+ xmlSecSize ii;
+
+ x509Data = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataX509Id);
+ if(x509Data == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataX509Id)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ 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) {
+ 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)) {
+ 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 */
+ }
+
+ ret = xmlSecGnuTLSKeyDataX509AdoptCert(x509Data, cert);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSKeyDataX509AdoptCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ cert = NULL; /* owned by x509Data now */
+ }
+
+ /* set in the key */
+ ret = xmlSecKeyAdoptData(key, x509Data);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyAdoptData",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "data=%s",
+ xmlSecErrorsSafeString(xmlSecKeyDataGetName(x509Data)));
+ goto done;
+ }
+ 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(priv_key != NULL) {
+ gnutls_x509_privkey_deinit(priv_key);
+ }
+ if(keyData != NULL) {
+ xmlSecKeyDataDestroy(keyData);
+ }
+ if(x509Data != NULL) {
+ xmlSecKeyDataDestroy(x509Data);
+ }
+ if(key != NULL) {
+ xmlSecKeyDestroy(key);
+ }
+ xmlSecPtrListFinalize(&certsList);
+ return(res);
}
/**
@@ -422,19 +634,48 @@ xmlSecGnuTLSAppKeysMngrCertLoadMemory(xmlSecKeysMngrPtr mngr,
const xmlSecByte* data,
xmlSecSize dataSize,
xmlSecKeyDataFormat format,
- xmlSecKeyDataType type ATTRIBUTE_UNUSED) {
+ xmlSecKeyDataType type) {
+ xmlSecKeyDataStorePtr x509Store;
+ gnutls_x509_crt_t cert;
+ int ret;
+
xmlSecAssert2(mngr != NULL, -1);
xmlSecAssert2(data != NULL, -1);
xmlSecAssert2(dataSize > 0, -1);
xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);
- /* TODO */
- xmlSecError(XMLSEC_ERRORS_HERE,
- NULL,
- "xmlSecGnuTLSAppKeysMngrCertLoadMemory",
- XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
- XMLSEC_ERRORS_NO_MESSAGE);
- return(-1);
+ x509Store = xmlSecKeysMngrGetDataStore(mngr, xmlSecGnuTLSX509StoreId);
+ if(x509Store == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeysMngrGetDataStore",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGnuTLSX509StoreId");
+ return(-1);
+ }
+
+ cert = xmlSecGnuTLSX509CertRead(data, dataSize, format);
+ if(cert == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509CertRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ ret = xmlSecGnuTLSX509StoreAdoptCert(x509Store, cert, type);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSX509StoreAdoptCert",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gnutls_x509_crt_deinit(cert);
+ return(-1);
+ }
+
+ return(0);
}
#endif /* XMLSEC_NO_X509 */
diff --git a/src/gnutls/asymkeys.c b/src/gnutls/asymkeys.c
index cbb43ae..e1f7f00 100644
--- a/src/gnutls/asymkeys.c
+++ b/src/gnutls/asymkeys.c
@@ -31,6 +31,51 @@
#include <xmlsec/gcrypt/crypto.h>
#include <gcrypt.h>
+static void xmlSecGnuTLSDestroyParams(gnutls_datum_t * params, xmlSecSize num) {
+ xmlSecSize ii;
+
+ xmlSecAssert(params != NULL);
+ for(ii = 0; ii < num; ++ii) {
+ gnutls_free(params[ii].data);
+ }
+}
+
+static void xmlSecGnuTLSDestroyMpis(gcry_mpi_t * mpis, xmlSecSize num) {
+ xmlSecSize ii;
+
+ xmlSecAssert(mpis != NULL);
+ for(ii = 0; ii < num; ++ii) {
+ gcry_mpi_release(mpis[ii]);
+ }
+}
+
+static int xmlSecGnuTLSConvertParamsToMpis(gnutls_datum_t * params, xmlSecSize paramsNum,
+ gcry_mpi_t * mpis, xmlSecSize mpisNum) {
+
+ xmlSecSize ii;
+ int err;
+
+ 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)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_mpi_scan",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(err));
+ xmlSecGnuTLSDestroyMpis(mpis, ii); /* destroy up to now */
+ return(-1);
+ }
+ }
+
+ /* done */
+ return(0);
+}
+
#ifndef XMLSEC_NO_DSA
/**
@@ -56,10 +101,86 @@ xmlSecGnuTLSKeyDataDsaGetKlass(void) {
*/
int
xmlSecGnuTLSKeyDataDsaAdoptPrivateKey(xmlSecKeyDataPtr data, gnutls_x509_privkey_t dsa_key) {
+ gnutls_datum_t params[5];
+ gcry_mpi_t mpis[5];
+ gcry_sexp_t priv_key = NULL;
+ gcry_sexp_t pub_key = NULL;
+ int rc;
+ int err;
+ int ret;
+
xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataDsaId), -1);
xmlSecAssert2(dsa_key != NULL, -1);
+ xmlSecAssert2(gnutls_x509_privkey_get_pk_algorithm(dsa_key) == GNUTLS_PK_DSA, -1);
- /* ALEKSEY_TODO */
+ /* get raw values */
+ err = gnutls_x509_privkey_export_dsa_raw(dsa_key,
+ &(params[0]), &(params[1]), &(params[2]),
+ &(params[3]), &(params[4]));
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_privkey_export_dsa_raw",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(-1);
+ }
+
+ /* 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);
+ xmlSecGnuTLSDestroyParams(params, sizeof(params)/sizeof(params[0]));
+ return(-1);
+ }
+ xmlSecGnuTLSDestroyParams(params, sizeof(params)/sizeof(params[0]));
+
+ /* 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)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_build(private/dsa)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(err));
+ 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)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_build(private/rsa)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(err));
+ gcry_sexp_release(priv_key);
+ xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+ return(-1);
+ }
+ xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+
+ ret = xmlSecGCryptKeyDataDsaAdoptKeyPair(data, pub_key, priv_key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGCryptKeyDataDsaAdoptKeyPair",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gcry_sexp_release(pub_key);
+ gcry_sexp_release(priv_key);
+ return(-1);
+ }
+
+ /* done, we "adopted" the key - destroy it! */
+ gnutls_x509_privkey_deinit(dsa_key);
return(0);
}
@@ -118,10 +239,87 @@ xmlSecGnuTLSKeyDataRsaGetKlass(void) {
*/
int
xmlSecGnuTLSKeyDataRsaAdoptPrivateKey(xmlSecKeyDataPtr data, gnutls_x509_privkey_t rsa_key) {
+ gnutls_datum_t params[6];
+ gcry_mpi_t mpis[6];
+ gcry_sexp_t priv_key = NULL;
+ gcry_sexp_t pub_key = NULL;
+ int rc;
+ int err;
+ int ret;
+
xmlSecAssert2(xmlSecKeyDataCheckId(data, xmlSecGnuTLSKeyDataRsaId), -1);
xmlSecAssert2(rsa_key != NULL, -1);
+ xmlSecAssert2(gnutls_x509_privkey_get_pk_algorithm(rsa_key) == GNUTLS_PK_RSA, -1);
- /* ALEKSEY_TODO */
+ /* get raw values */
+ err = gnutls_x509_privkey_export_rsa_raw(rsa_key,
+ &(params[0]), &(params[1]), &(params[2]),
+ &(params[3]), &(params[4]), &(params[5]));
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_privkey_export_rsa_raw",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ return(-1);
+ }
+
+ /* 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);
+ xmlSecGnuTLSDestroyParams(params, sizeof(params)/sizeof(params[0]));
+ return(-1);
+ }
+ xmlSecGnuTLSDestroyParams(params, sizeof(params)/sizeof(params[0]));
+
+ /* build expressions */
+ 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)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_build(private/rsa)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(err));
+ 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)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gcry_sexp_build(private/rsa)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_GNUTLS_GCRYPT_REPORT_ERROR(err));
+ gcry_sexp_release(priv_key);
+ xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+ return(-1);
+ }
+ xmlSecGnuTLSDestroyMpis(mpis, sizeof(mpis)/sizeof(mpis[0]));
+
+ ret = xmlSecGCryptKeyDataRsaAdoptKeyPair(data, pub_key, priv_key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGCryptKeyDataRsaAdoptKeyPair",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ gcry_sexp_release(pub_key);
+ gcry_sexp_release(priv_key);
+ return(-1);
+ }
+
+ /* done, we "adopted" the key - destroy it! */
+ gnutls_x509_privkey_deinit(rsa_key);
return(0);
}
diff --git a/src/gnutls/x509.c b/src/gnutls/x509.c
index 970f5f3..3326dd7 100644
--- a/src/gnutls/x509.c
+++ b/src/gnutls/x509.c
@@ -1425,6 +1425,7 @@ xmlSecGnuTLSX509CertGetKey(gnutls_x509_crt_t cert) {
}
switch(alg) {
+#ifndef XMLSEC_NO_RSA
case GNUTLS_PK_RSA:
{
gnutls_datum_t m, e;
@@ -1463,7 +1464,9 @@ xmlSecGnuTLSX509CertGetKey(gnutls_x509_crt_t cert) {
/* m and e are owned by data now */
}
break;
+#endif /* XMLSEC_NO_RSA */
+#ifndef XMLSEC_NO_DSA
case GNUTLS_PK_DSA:
{
gnutls_datum_t p, q, g, y;
@@ -1504,6 +1507,7 @@ xmlSecGnuTLSX509CertGetKey(gnutls_x509_crt_t cert) {
/* p, q, g and y are owned by data now */
}
break;
+#endif /* XMLSEC_NO_DSA */
default:
{
@@ -1597,11 +1601,11 @@ xmlSecGnuTLSKeyDataRawX509CertBinRead(xmlSecKeyDataId id, xmlSecKeyPtr key,
xmlSecAssert2(bufSize > 0, -1);
xmlSecAssert2(keyInfoCtx != NULL, -1);
- cert = xmlSecGnuTLSX509CertDerRead(buf, bufSize);
+ cert = xmlSecGnuTLSX509CertRead(buf, bufSize, xmlSecKeyDataFormatCertDer);
if(cert == NULL) {
xmlSecError(XMLSEC_ERRORS_HERE,
NULL,
- "xmlSecGnuTLSX509CertDerRead",
+ "xmlSecGnuTLSX509CertRead",
XMLSEC_ERRORS_R_XMLSEC_FAILED,
XMLSEC_ERRORS_NO_MESSAGE);
return(-1);
diff --git a/src/gnutls/x509utils.c b/src/gnutls/x509utils.c
index e87e8cf..14c292f 100644
--- a/src/gnutls/x509utils.c
+++ b/src/gnutls/x509utils.c
@@ -22,6 +22,12 @@
#include <libxml/tree.h>
+
+
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gnutls/pkcs12.h>
+
#include <xmlsec/xmlsec.h>
#include <xmlsec/xmltree.h>
#include <xmlsec/keys.h>
@@ -281,7 +287,6 @@ xmlSecGnuTLSX509CertGetIssuerSerial(gnutls_x509_crt_t cert) {
xmlFree(buf);
return(NULL);
}
- printf("DEBUG: serial number is %s\n", res);
/* done */
xmlFree(buf);
@@ -367,18 +372,37 @@ xmlSecGnuTLSX509CertBase64DerRead(xmlChar* buf) {
return(NULL);
}
- return(xmlSecGnuTLSX509CertDerRead((const xmlSecByte*)buf, ret));
+ return(xmlSecGnuTLSX509CertRead((const xmlSecByte*)buf, ret, xmlSecKeyDataFormatCertDer));
}
gnutls_x509_crt_t
-xmlSecGnuTLSX509CertDerRead(const xmlSecByte* buf, xmlSecSize size) {
+xmlSecGnuTLSX509CertRead(const xmlSecByte* buf, xmlSecSize size, xmlSecKeyDataFormat format) {
gnutls_x509_crt_t cert = NULL;
+ gnutls_x509_crt_fmt_t fmt;
gnutls_datum_t data;
int err;
xmlSecAssert2(buf != NULL, NULL);
xmlSecAssert2(size > 0, NULL);
+ /* figure out format */
+ switch(format) {
+ case xmlSecKeyDataFormatCertPem:
+ fmt = GNUTLS_X509_FMT_PEM;
+ break;
+ case xmlSecKeyDataFormatCertDer:
+ fmt = GNUTLS_X509_FMT_DER;
+ break;
+ default:
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_INVALID_FORMAT,
+ "format=%d", format);
+ return(NULL);
+ }
+
+ /* read cert */
err = gnutls_x509_crt_init(&cert);
if(err != GNUTLS_E_SUCCESS) {
xmlSecError(XMLSEC_ERRORS_HERE,
@@ -391,7 +415,7 @@ xmlSecGnuTLSX509CertDerRead(const xmlSecByte* buf, xmlSecSize size) {
data.data = (unsigned char*)buf;
data.size = size;
- err = gnutls_x509_crt_import(cert, &data, GNUTLS_X509_FMT_DER);
+ err = gnutls_x509_crt_import(cert, &data, fmt);
if(err != GNUTLS_E_SUCCESS) {
xmlSecError(XMLSEC_ERRORS_HERE,
NULL,
@@ -538,7 +562,7 @@ xmlSecGnuTLSASN1IntegerWrite(const unsigned char * data, size_t len) {
int shift = 0;
xmlSecAssert2(data != NULL, NULL);
- xmlSecAssert2(len <= 8, NULL);
+ xmlSecAssert2(len <= 9, NULL);
/* HACK : to be fixed after GnuTLS provides a way to read opaque ASN1 integer */
for(ii = len; ii > 0; --ii, shift += 8) {
@@ -559,4 +583,327 @@ xmlSecGnuTLSASN1IntegerWrite(const unsigned char * data, size_t len) {
return(res);
}
+/*************************************************************************
+ *
+ * pkcs12 utils/helpers
+ *
+ ************************************************************************/
+int
+xmlSecGnuTLSPkcs12LoadMemory(const xmlSecByte* data, xmlSecSize dataSize,
+ const char *pwd,
+ gnutls_x509_privkey_t * priv_key,
+ xmlSecPtrListPtr certsList)
+{
+ gnutls_pkcs12_t pkcs12 = NULL;
+ gnutls_pkcs12_bag_t bag = NULL;
+ gnutls_x509_crt_t cert = NULL;
+ gnutls_datum_t datum;
+ int res = -1;
+ int idx;
+ int err;
+ int ret;
+
+ xmlSecAssert2(data != NULL, -1);
+ xmlSecAssert2(dataSize > 0, -1);
+ xmlSecAssert2(priv_key != NULL, -1);
+ xmlSecAssert2((*priv_key) == NULL, -1);
+ xmlSecAssert2(certsList != NULL, -1);
+
+ /* read pkcs12 in internal structure */
+ err = gnutls_pkcs12_init(&pkcs12);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ datum.data = (unsigned char *)data;
+ datum.size = dataSize;
+ err = gnutls_pkcs12_import(pkcs12, &datum, GNUTLS_X509_FMT_DER, 0);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_import",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ /* verify */
+ err = gnutls_pkcs12_verify_mac(pkcs12, pwd);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_verify_mac",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ /* scan the pkcs structure and find the first private key */
+ for(idx = 0; ; ++idx) {
+ int bag_type;
+ int elements_in_bag;
+ int ii;
+
+ err = gnutls_pkcs12_bag_init(&bag);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_bag_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ err = gnutls_pkcs12_get_bag(pkcs12, idx, bag);
+ if(err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+ /* scanned the whole pkcs12, stop */
+ break;
+ } else if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_get_bag",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ /* check if we need to decrypt the bag */
+ bag_type = gnutls_pkcs12_bag_get_type(bag, 0);
+ if(bag_type < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_bag_get_type",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(bag_type));
+ goto done;
+ }
+ if(bag_type == GNUTLS_BAG_ENCRYPTED) {
+ err = gnutls_pkcs12_bag_decrypt(bag, pwd);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_bag_decrypt",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+ }
+
+ /* scan elements in bag */
+ elements_in_bag = gnutls_pkcs12_bag_get_count(bag);
+ if(elements_in_bag < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_bag_get_count",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(bag_type));
+ goto done;
+ }
+ for(ii = 0; ii < elements_in_bag; ++ii) {
+ bag_type = gnutls_pkcs12_bag_get_type(bag, ii);
+ if(bag_type < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_bag_get_type",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(bag_type));
+ goto done;
+ }
+
+ err = gnutls_pkcs12_bag_get_data(bag, ii, &datum);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_pkcs12_bag_get_data",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ switch(bag_type) {
+ case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
+ case GNUTLS_BAG_PKCS8_KEY:
+ /* we want only the first private key */
+ if((*priv_key) == NULL) {
+ err = gnutls_x509_privkey_init(priv_key);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_privkey_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ err = gnutls_x509_privkey_import_pkcs8((*priv_key),
+ &datum, GNUTLS_X509_FMT_DER,
+ pwd,
+ (bag_type == GNUTLS_BAG_PKCS8_KEY) ? GNUTLS_PKCS_PLAIN : 0);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_privkey_import_pkcs8",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+ }
+ break;
+ case GNUTLS_BAG_CERTIFICATE:
+ err = gnutls_x509_crt_init(&cert);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_init",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ err = gnutls_x509_crt_import(cert, &datum, GNUTLS_X509_FMT_DER);
+ if(err != GNUTLS_E_SUCCESS) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_crt_import",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(err));
+ goto done;
+ }
+
+ ret = xmlSecPtrListAdd(certsList, cert);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListAdd(certsList)",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ goto done;
+ }
+ cert = NULL; /* owned by certsList now */
+ break;
+ default:
+ /* ignore unknown bag element */
+ break;
+ }
+ }
+
+ /* done with bag */
+ gnutls_pkcs12_bag_deinit(bag);
+ bag = NULL;
+ }
+
+ /* check we have private key */
+ if((*priv_key) == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "Private key was not found in pkcs12 object");
+ goto done;
+ }
+
+ /* success!!! */
+ res = 0;
+
+done:
+ if(cert != NULL) {
+ gnutls_x509_crt_deinit(cert);
+ }
+ if(bag != NULL) {
+ gnutls_pkcs12_bag_deinit(bag);
+ }
+ if(pkcs12 != NULL) {
+ gnutls_pkcs12_deinit(pkcs12);
+ }
+ return(res);
+}
+
+xmlSecKeyDataPtr
+xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey(gnutls_x509_privkey_t priv_key) {
+ xmlSecKeyDataPtr res = NULL;
+ int key_alg;
+ int ret;
+
+ xmlSecAssert2(priv_key != NULL, NULL);
+
+ /* create key value data */
+ key_alg = gnutls_x509_privkey_get_pk_algorithm(priv_key);
+ if(key_alg < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_privkey_get_pk_algorithm",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ XMLSEC_GNUTLS_REPORT_ERROR(key_alg));
+ return (NULL);
+ }
+ switch(key_alg) {
+#ifndef XMLSEC_NO_RSA
+ case GNUTLS_PK_RSA:
+ res = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataRsaId);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyDataCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGnuTLSKeyDataRsaId");
+ return(NULL);
+ }
+
+ ret = xmlSecGnuTLSKeyDataRsaAdoptPrivateKey(res, priv_key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSKeyDataRsaAdoptPrivateKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGnuTLSKeyDataRsaId");
+ xmlSecKeyDataDestroy(res);
+ return(NULL);
+ }
+ break;
+#endif /* XMLSEC_NO_RSA */
+
+#ifndef XMLSEC_NO_DSA
+ case GNUTLS_PK_DSA:
+ res = xmlSecKeyDataCreate(xmlSecGnuTLSKeyDataDsaId);
+ if(res == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecKeyDataCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGnuTLSKeyDataDsaId");
+ return(NULL);
+ }
+
+ ret = xmlSecGnuTLSKeyDataDsaAdoptPrivateKey(res, priv_key);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecGnuTLSKeyDataDsaAdoptPrivateKey",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "xmlSecGnuTLSKeyDataDsaId");
+ xmlSecKeyDataDestroy(res);
+ return(NULL);
+ }
+ break;
+#endif /* XMLSEC_NO_DSA */
+ default:
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "gnutls_x509_privkey_get_pk_algorithm",
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
+ "Unsupported algorithm %d", (int)key_alg);
+ return(NULL);
+ }
+
+ /* done */
+ return(res);
+}
+
+
+
#endif /* XMLSEC_NO_X509 */
diff --git a/src/gnutls/x509utils.h b/src/gnutls/x509utils.h
index b0727f2..da5325c 100644
--- a/src/gnutls/x509utils.h
+++ b/src/gnutls/x509utils.h
@@ -34,7 +34,7 @@ xmlSecPtrListId xmlSecGnuTLSX509CrtListGetKlass (void);
/*************************************************************************
*
- * Utils/helpers
+ * x509 utils/helpers
*
************************************************************************/
gnutls_x509_crt_t xmlSecGnuTLSX509CertDup (gnutls_x509_crt_t src);
@@ -42,8 +42,9 @@ xmlChar * xmlSecGnuTLSX509CertGetSubjectDN (gnutls_x509_crt
xmlChar * xmlSecGnuTLSX509CertGetIssuerDN (gnutls_x509_crt_t cert);
xmlChar * xmlSecGnuTLSX509CertGetIssuerSerial (gnutls_x509_crt_t cert);
xmlChar * xmlSecGnuTLSX509CertGetSKI (gnutls_x509_crt_t cert);
-gnutls_x509_crt_t xmlSecGnuTLSX509CertDerRead (const xmlSecByte* buf,
- xmlSecSize size);
+gnutls_x509_crt_t xmlSecGnuTLSX509CertRead (const xmlSecByte* buf,
+ xmlSecSize size,
+ xmlSecKeyDataFormat format);
gnutls_x509_crt_t xmlSecGnuTLSX509CertBase64DerRead (xmlChar* buf);
xmlChar* xmlSecGnuTLSX509CertBase64DerWrite (gnutls_x509_crt_t cert,
int base64LineWrap);
@@ -55,6 +56,21 @@ xmlChar* xmlSecGnuTLSASN1IntegerWrite (const unsigned
size_t len);
+
+/*************************************************************************
+ *
+ * pkcs12 utils/helpers
+ *
+ ************************************************************************/
+int xmlSecGnuTLSPkcs12LoadMemory (const xmlSecByte* data,
+ xmlSecSize dataSize,
+ const char *pwd,
+ gnutls_x509_privkey_t * priv_key,
+ xmlSecPtrListPtr certsList);
+
+xmlSecKeyDataPtr xmlSecGnuTLSCreateKeyDataAndAdoptPrivKey(gnutls_x509_privkey_t priv_key);
+
+
#endif /* XMLSEC_NO_X509 */
#ifdef __cplusplus
diff --git a/src/list.c b/src/list.c
index 4ab2677..d1a0053 100644
--- a/src/list.c
+++ b/src/list.c
@@ -368,6 +368,32 @@ xmlSecPtrListRemove(xmlSecPtrListPtr list, xmlSecSize pos) {
}
/**
+ * xmlSecPtrListRemoveAndReturn:
+ * @list: the pointer to list.
+ * @pos: the position.
+ *
+ * Remove the list item at the position @pos and return it back.
+ *
+ * Returns: the pointer to the list item.
+ */
+xmlSecPtr
+xmlSecPtrListRemoveAndReturn(xmlSecPtrListPtr list, xmlSecSize pos) {
+ xmlSecPtr res;
+
+ xmlSecAssert2(xmlSecPtrListIsValid(list), NULL);
+ xmlSecAssert2(list->data != NULL, NULL);
+ xmlSecAssert2(pos < list->use, NULL);
+
+ res = list->data[pos];
+ list->data[pos] = NULL;
+ if(pos == list->use - 1) {
+ --list->use;
+ }
+ return(res);
+}
+
+
+/**
* xmlSecPtrListDebugDump:
* @list: the pointer to list.
* @output: the pointer to output FILE.
diff --git a/src/openssl/app.c b/src/openssl/app.c
index 1319b07..d172dcf 100644
--- a/src/openssl/app.c
+++ b/src/openssl/app.c
@@ -685,7 +685,7 @@ xmlSecOpenSSLAppPkcs12LoadBIO(BIO* bio, const char *pwd,
X509 *cert = NULL;
X509 *tmpcert = NULL;
int i;
- int has_cert;
+ int has_cert;
int ret;
xmlSecAssert2(bio != NULL, NULL);
@@ -757,50 +757,51 @@ xmlSecOpenSSLAppPkcs12LoadBIO(BIO* bio, const char *pwd,
}
}
- /*
+ /*
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".
+ 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;
+ 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);
+ xmlSecAssert2(sk_X509_value(chain, i), NULL);
- if(X509_cmp(sk_X509_value(chain, i), cert) != 0) {
- has_cert = 1;
- break;
- }
+ 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;
- }
+ }
+
+ 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,
diff --git a/tests/testrun.sh b/tests/testrun.sh
index 7642dc2..c1f629b 100755
--- a/tests/testrun.sh
+++ b/tests/testrun.sh
@@ -66,7 +66,7 @@ cert_format=$file_format
#
# GCrypt/GnuTLS only supports DER format for now, others are good to go with PKCS12
#
-if [ "z$crypto" != "zgcrypt" -a "z$crypto" != "zgnutls" ] ; then
+if [ "z$crypto" != "zgcrypt" ] ; then
priv_key_option="--pkcs12"
priv_key_format="p12"
else
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]