Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix x509data->keyCert when loading a key from a cert #546

Merged
merged 2 commits into from
Feb 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 59 additions & 14 deletions src/gnutls/app.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,38 +270,64 @@ xmlSecGnuTLSAppKeyCertLoad(xmlSecKeyPtr key, const char* filename,
*/
int
xmlSecGnuTLSAppKeyCertLoadMemory(xmlSecKeyPtr key,
const xmlSecByte* data,
xmlSecSize dataSize,
xmlSecKeyDataFormat format) {
gnutls_x509_crt_t cert;
const xmlSecByte* data, xmlSecSize dataSize, xmlSecKeyDataFormat format)
{
gnutls_x509_crt_t cert = NULL;
gnutls_x509_crt_t keyCert = NULL;
xmlSecKeyDataPtr keyData;
int ret;
int res = -1;

xmlSecAssert2(key != NULL, -1);
xmlSecAssert2(data != NULL, -1);
xmlSecAssert2(dataSize > 0, -1);
xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, -1);

/* read cert and make a copy for the keyCert */
cert = xmlSecGnuTLSX509CertRead(data, dataSize, format);
if(cert == NULL) {
xmlSecInternalError("xmlSecGnuTLSX509CertRead", NULL);
goto done;
}

keyCert = xmlSecGnuTLSX509CertDup(cert);
if(keyCert == NULL) {
xmlSecInternalError("xmlSecGnuTLSX509CertDup", NULL);
goto done;
}

/* add both cert and keyCert to the keyData */
keyData = xmlSecKeyEnsureData(key, xmlSecGnuTLSKeyDataX509Id);
if(keyData == NULL) {
xmlSecInternalError("xmlSecKeyEnsureData", NULL);
return(-1);
goto done;
}

cert = xmlSecGnuTLSX509CertRead(data, dataSize, format);
if(cert == NULL) {
xmlSecInternalError("xmlSecGnuTLSX509CertRead", NULL);
return(-1);
ret = xmlSecGnuTLSKeyDataX509AdoptKeyCert(keyData, keyCert);
if(ret < 0) {
xmlSecInternalError("xmlSecGnuTLSKeyDataX509AdoptKeyCert", NULL);
goto done;
}
keyCert = NULL; /* owned by keyData now */

ret = xmlSecGnuTLSKeyDataX509AdoptCert(keyData, cert);
if(ret < 0) {
xmlSecInternalError("xmlSecGnuTLSKeyDataX509AdoptCert", NULL);
gnutls_x509_crt_deinit(cert);
return(-1);
goto done;
}
cert = NULL; /* owned by key data now */

return(0);
/* success */
res = 0;

done:
if(cert != NULL) {
gnutls_x509_crt_deinit(cert);
}
if(keyCert != NULL) {
gnutls_x509_crt_deinit(keyCert);
}
return(res);
}

/**
Expand Down Expand Up @@ -640,20 +666,27 @@ xmlSecGnuTLSAppKeyFromCertLoadMemory(const xmlSecByte* data, xmlSecSize dataSize
xmlSecKeyDataPtr keyData = NULL;
xmlSecKeyDataPtr x509Data = NULL;
gnutls_x509_crt_t cert = NULL;
gnutls_x509_crt_t keyCert = NULL;
xmlSecKeyPtr res = NULL;
int ret;

xmlSecAssert2(data != NULL, NULL);
xmlSecAssert2(dataSize > 0, NULL);
xmlSecAssert2(format != xmlSecKeyDataFormatUnknown, NULL);

/* read cert */
/* read cert and make a copy for keyCert */
cert = xmlSecGnuTLSX509CertRead(data, dataSize, format);
if(cert == NULL) {
xmlSecInternalError("xmlSecGnuTLSX509CertRead", NULL);
goto done;
}

keyCert = xmlSecGnuTLSX509CertDup(cert);
if(keyCert == NULL) {
xmlSecInternalError("xmlSecGnuTLSX509CertDup", NULL);
goto done;
}

/* create key */
key = xmlSecKeyCreate();
if(key == NULL) {
Expand Down Expand Up @@ -682,11 +715,20 @@ xmlSecGnuTLSAppKeyFromCertLoadMemory(const xmlSecByte* data, xmlSecSize dataSize
xmlSecInternalError("xmlSecKeyEnsureData", NULL);
goto done;
}
ret = xmlSecGnuTLSKeyDataX509AdoptKeyCert(x509Data, cert);

/* add cert and key cert */
ret = xmlSecGnuTLSKeyDataX509AdoptKeyCert(x509Data, keyCert);
if(ret < 0) {
xmlSecInternalError("xmlSecGnuTLSKeyDataX509AdoptKeyCert", NULL);
goto done;
}
keyCert = NULL; /* owned by x509Data now */

ret = xmlSecGnuTLSKeyDataX509AdoptCert(x509Data, cert);
if(ret < 0) {
xmlSecInternalError("xmlSecGnuTLSKeyDataX509AdoptCert", NULL);
goto done;
}
cert = NULL; /* owned by x509Data now */

/* success */
Expand All @@ -697,6 +739,9 @@ xmlSecGnuTLSAppKeyFromCertLoadMemory(const xmlSecByte* data, xmlSecSize dataSize
if(cert != NULL) {
gnutls_x509_crt_deinit(cert);
}
if(keyCert != NULL) {
gnutls_x509_crt_deinit(keyCert);
}
if(keyData != NULL) {
xmlSecKeyDataDestroy(keyData);
}
Expand Down
70 changes: 43 additions & 27 deletions src/mscng/app.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ xmlSecKeyPtr
xmlSecMSCngAppKeyLoadMemory(const xmlSecByte* data, xmlSecSize dataSize, xmlSecKeyDataFormat format,
const char *pwd, void* pwdCallback, void* pwdCallbackCtx) {
PCCERT_CONTEXT pCert = NULL;
PCCERT_CONTEXT tmpcert = NULL;
PCCERT_CONTEXT pCertChain = NULL;
PCCERT_CONTEXT pKeyCert = NULL;
xmlSecKeyDataPtr x509Data = NULL;
xmlSecKeyDataPtr keyData = NULL;
xmlSecKeyPtr key = NULL;
Expand All @@ -206,74 +207,89 @@ xmlSecMSCngAppKeyLoadMemory(const xmlSecByte* data, xmlSecSize dataSize, xmlSecK
UNREFERENCED_PARAMETER(pwdCallback);
UNREFERENCED_PARAMETER(pwdCallbackCtx);

/* read cert and make a copy for cert chain and keyCert */
XMLSEC_SAFE_CAST_SIZE_TO_ULONG(dataSize, dwDataSize, goto done, NULL);
pCert = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, data, dwDataSize);
if(pCert == NULL) {
xmlSecMSCngLastError("CertCreateCertificateContext", NULL);
goto done;
}

x509Data = xmlSecKeyDataCreate(xmlSecMSCngKeyDataX509Id);
if(x509Data == NULL) {
xmlSecInternalError("xmlSecKeyDataCreate", NULL);
pCertChain = CertDuplicateCertificateContext(pCert);
if(pCertChain == NULL) {
xmlSecMSCngLastError("CertDuplicateCertificateContext", NULL);
goto done;
}

tmpcert = CertDuplicateCertificateContext(pCert);
if(tmpcert == NULL) {
xmlSecMSCngLastError("CertDuplicateCertificateContext",
xmlSecKeyDataGetName(x509Data));
pKeyCert = CertDuplicateCertificateContext(pCert);
if(pKeyCert == NULL) {
xmlSecMSCngLastError("CertDuplicateCertificateContext", NULL);
goto done;
}

ret = xmlSecMSCngKeyDataX509AdoptKeyCert(x509Data, tmpcert);
if(ret < 0) {
xmlSecInternalError("xmlSecMSCngKeyDataX509AdoptKeyCert",
/* create key */
key = xmlSecKeyCreate();
if(key == NULL) {
xmlSecInternalError("xmlSecKeyCreate",
xmlSecKeyDataGetName(x509Data));
goto done;
}
tmpcert = NULL;

keyData = xmlSecMSCngCertAdopt(pCert, xmlSecKeyDataTypePublic);
if(keyData == NULL) {
xmlSecInternalError("xmlSecMSCngCertAdopt",
xmlSecKeyDataGetName(x509Data));
xmlSecInternalError("xmlSecMSCngCertAdopt", NULL);
goto done;
}
pCert = NULL;
pCert = NULL; /* owned by keyData now */

key = xmlSecKeyCreate();
if(key == NULL) {
xmlSecInternalError("xmlSecKeyCreate",
xmlSecKeyDataGetName(x509Data));
ret = xmlSecKeySetValue(key, keyData);
if(ret < 0) {
xmlSecInternalError("xmlSecKeySetValue", NULL);
goto done;
}
keyData = NULL;

/* add cert and keyCert to x509 data and add it to the key */
x509Data = xmlSecKeyDataCreate(xmlSecMSCngKeyDataX509Id);
if(x509Data == NULL) {
xmlSecInternalError("xmlSecKeyDataCreate", NULL);
goto done;
}

ret = xmlSecKeySetValue(key, keyData);
ret = xmlSecMSCngKeyDataX509AdoptKeyCert(x509Data, pKeyCert);
if(ret < 0) {
xmlSecInternalError("xmlSecKeySetValue",
xmlSecKeyDataGetName(x509Data));
xmlSecInternalError("xmlSecMSCngKeyDataX509AdoptKeyCert", NULL);
goto done;
}
keyData = NULL;
pKeyCert = NULL; /* owned by x509Data data now */

ret = xmlSecMSCngKeyDataX509AdoptCert(x509Data, pCertChain);
if(ret < 0) {
xmlSecInternalError("xmlSecMSCngKeyDataX509AdoptCert", NULL);
goto done;
}
pCertChain = NULL; /* owned by x509Data data now */

ret = xmlSecKeyAdoptData(key, x509Data);
if(ret < 0) {
xmlSecInternalError("xmlSecKeyAdoptData",
xmlSecKeyDataGetName(x509Data));
xmlSecInternalError("xmlSecKeyAdoptData", NULL);
goto done;
}
x509Data = NULL;

/* success */
res = key;
key = NULL;

done:
if(pCert != NULL) {
CertFreeCertificateContext(pCert);
}
if(tmpcert != NULL) {
CertFreeCertificateContext(tmpcert);
if(pCertChain != NULL) {
CertFreeCertificateContext(pCertChain);
}
if(pKeyCert != NULL) {
CertFreeCertificateContext(pKeyCert);
}
if(x509Data != NULL) {
xmlSecKeyDataDestroy(x509Data);
Expand Down
22 changes: 21 additions & 1 deletion src/mscrypto/app.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ xmlSecMSCryptoAppKeyCertLoad(xmlSecKeyPtr key, const char* filename,
int
xmlSecMSCryptoAppKeyCertLoadMemory(xmlSecKeyPtr key, const xmlSecByte* data, xmlSecSize dataSize,
xmlSecKeyDataFormat format) {
PCCERT_CONTEXT pCert;
PCCERT_CONTEXT pCert, pKeyCert;
xmlSecKeyDataPtr kdata;
DWORD dwDataSize;
int ret;
Expand All @@ -389,19 +389,39 @@ xmlSecMSCryptoAppKeyCertLoadMemory(xmlSecKeyPtr key, const xmlSecByte* data, xml
case xmlSecKeyDataFormatDer:
case xmlSecKeyDataFormatCertDer:
XMLSEC_SAFE_CAST_SIZE_TO_ULONG(dataSize, dwDataSize, return(-1), NULL);

/* read cert and make a copy for key cert */
pCert = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, data, dwDataSize);
if (NULL == pCert) {
xmlSecInternalError2("CertCreateCertificateContext", xmlSecKeyDataGetName(kdata),
"format=" XMLSEC_ENUM_FMT, XMLSEC_ENUM_CAST(format));
return(-1);
}
pKeyCert = CertDuplicateCertificateContext(pCert);
if(pKeyCert == NULL) {
xmlSecMSCryptoError("CertDuplicateCertificateContext", xmlSecKeyDataGetName(kdata));
CertFreeCertificateContext(pCert);
return(-1);
}

/* add cert and key cert */
ret = xmlSecMSCryptoKeyDataX509AdoptCert(kdata, pCert);
if(ret < 0) {
xmlSecInternalError("xmlSecMSCryptoKeyDataX509AdoptCert", xmlSecKeyDataGetName(kdata));
CertFreeCertificateContext(pCert);
CertFreeCertificateContext(pKeyCert);
return(-1);
}
pCert = NULL; /* owned by kdata */

ret = xmlSecMSCryptoKeyDataX509AdoptKeyCert(kdata, pKeyCert);
if(ret < 0) {
xmlSecInternalError("xmlSecMSCryptoKeyDataX509AdoptKeyCert", xmlSecKeyDataGetName(kdata));
CertFreeCertificateContext(pKeyCert);
return(-1);
}
pKeyCert = NULL; /* owned by kdata */

break;
default:
xmlSecOtherError2(XMLSEC_ERRORS_R_INVALID_FORMAT, xmlSecKeyDataGetName(kdata),
Expand Down
Loading