Skip to content

Commit

Permalink
(xmlsec-gnutls) Added a check to ensure that the key certificat match…
Browse files Browse the repository at this point in the history
…es the key. (#696)
  • Loading branch information
lsh123 authored Jul 13, 2023
1 parent 6e1c100 commit 7884d21
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 12 deletions.
5 changes: 3 additions & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,11 @@ <h1>XML Security Library</h1>
(use "--with-default-crypto" option to force the selection).</li>
<li>Fixed the static libraries build with "--enable-static-linking" option on MinGW.</li>
<li>(xmlsec-openssl) Fixed padding for GOST 2001 and 2012 signatures.</li>
<li>(xmlsec-nss) Added a check to ensure that a key certificates match the key.</li>
<li>(xmlsec-nss) Added support for reading PEM certificates.</li>
<li>(xmlsec-nss) Added a check to ensure that the key certificat matches the key.</li>
<li>(xmlsec-gnutls) Added support for GOST R 34.11-94, GOST R 34.11-2012 256 bit, and GOST R 34.11-2012 512 bit digest algorithms.</li>
<li>(xmlsec-gnutls) Added support GOST R 34.10-2001, GOST R 34.11-2012 256 bit, and GOST R 34.11-2012 512 bit signature algorithms.</li>
<li>(xmlsec-nss) Support reading PEM certificates.</li>
<li>(xmlsec-gnutls) Added a check to ensure that the key certificat matches the key.</li>
<li>Several other small fixes (<a href="https://github.com/lsh123/xmlsec/commits/master">more details</a>).</li>
</ul>
</li>
Expand Down
91 changes: 90 additions & 1 deletion src/gnutls/app.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,83 @@ xmlSecGnuTLSAppKeyCertLoad(xmlSecKeyPtr key, const char* filename, xmlSecKeyData
return(0);
}


/* returns 1 if matches, 0 if not, or a negative value on error */
static int
xmlSecGnuTLSAppCheckCertMatchesKey(xmlSecKeyPtr key, gnutls_x509_crt_t cert) {
xmlSecKeyDataPtr keyData = NULL;
gnutls_pubkey_t pubkey = NULL;
gnutls_pubkey_t cert_pubkey = NULL;
gnutls_datum_t der_pubkey = { NULL, 0 };
gnutls_datum_t der_cert_pubkey = { NULL, 0 };
int err;
int res = -1;

xmlSecAssert2(key != NULL, -1);
xmlSecAssert2(cert != NULL, -1);

/* get key's pubkey and its der encoding */
keyData = xmlSecKeyGetValue(key);
if(keyData == NULL) {
res = 0; /* no key -> no match */
goto done;
}
pubkey = xmlSecGnuTLSAsymKeyDataGetPublicKey(keyData);
if(pubkey == NULL) {
xmlSecInternalError("xmlSecGnuTLSAsymKeyDataGetPublicKey", NULL);
goto done;
}
err = gnutls_pubkey_export2(pubkey, GNUTLS_X509_FMT_DER, &der_pubkey);
if((err != GNUTLS_E_SUCCESS) || (der_pubkey.data == NULL)) {
xmlSecGnuTLSError("gnutls_pubkey_export2", err, NULL);
goto done;
}

/* get certs's pubkey and its der encoding */
err = gnutls_pubkey_init(&cert_pubkey);
if (err != GNUTLS_E_SUCCESS) {
xmlSecGnuTLSError("gnutls_pubkey_init", err, NULL);
goto done;
}

err = gnutls_pubkey_import_x509(cert_pubkey, cert, 0);
if (err != GNUTLS_E_SUCCESS) {
xmlSecGnuTLSError("gnutls_pubkey_import_x509", err, NULL);
goto done;
}
err = gnutls_pubkey_export2(cert_pubkey, GNUTLS_X509_FMT_DER, &der_cert_pubkey);
if((err != GNUTLS_E_SUCCESS) || (der_cert_pubkey.data == NULL)) {
xmlSecGnuTLSError("gnutls_pubkey_export2", err, NULL);
goto done;
}

/* compare */
if(der_pubkey.size != der_cert_pubkey.size) {
res = 0; /* different size -> no match */
goto done;
}
if(memcmp(der_pubkey.data, der_cert_pubkey.data, der_pubkey.size) != 0) {
res = 0; /* different data -> no match */
goto done;
}

/* match! */
res = 1;

done:
if (cert_pubkey) {
gnutls_pubkey_deinit(cert_pubkey);
}
if(der_pubkey.data != NULL) {
gnutls_free(der_pubkey.data);
}
if(der_cert_pubkey.data != NULL) {
gnutls_free(der_cert_pubkey.data);
}
return(res);
}


/**
* xmlSecGnuTLSAppKeyCertLoadMemory:
* @key: the pointer to key.
Expand All @@ -300,6 +377,7 @@ xmlSecGnuTLSAppKeyCertLoadMemory(xmlSecKeyPtr key, const xmlSecByte* data, xmlSe
) {
gnutls_x509_crt_t cert = NULL;
xmlSecKeyDataPtr x509Data;
int isKeyCert = 0;
int ret;
int res = -1;

Expand All @@ -321,8 +399,19 @@ xmlSecGnuTLSAppKeyCertLoadMemory(xmlSecKeyPtr key, const xmlSecByte* data, xmlSe
xmlSecInternalError("xmlSecKeyEnsureData", NULL);
goto done;
}

/* do we want to add this cert as a key cert? */
if(xmlSecGnuTLSKeyDataX509GetKeyCert(x509Data) == NULL) {
/* TODO: check if cert matches the key */
ret = xmlSecGnuTLSAppCheckCertMatchesKey(key, cert);
if(ret < 0) {
xmlSecInternalError("xmlSecGnuTLSAppCheckCertMatchesKey", NULL);
goto done;
}
if(ret == 1) {
isKeyCert = 1;
}
}
if(isKeyCert != 0) {
ret = xmlSecGnuTLSKeyDataX509AdoptKeyCert(x509Data, cert);
if(ret < 0) {
xmlSecInternalError("xmlSecGnuTLSKeyDataX509AdoptKeyCert", NULL);
Expand Down
12 changes: 4 additions & 8 deletions src/gnutls/asymkeys.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,6 @@ static int xmlSecGnuTLSAsymKeyDataGenerate (xmlSecKeyDataPt
static int xmlSecGnuTLSAsymKeyDataDuplicate (xmlSecKeyDataPtr dst,
xmlSecKeyDataPtr src);

static gnutls_pubkey_t xmlSecGnuTLSAsymKeyDataGetPublicKey (xmlSecKeyDataPtr data);
static gnutls_privkey_t xmlSecGnuTLSAsymKeyDataGetPrivateKey (xmlSecKeyDataPtr data);
static xmlSecKeyDataType xmlSecGnuTLSAsymKeyDataGetType (xmlSecKeyDataPtr data);
static xmlSecSize xmlSecGnuTLSAsymKeyDataGetSize (xmlSecKeyDataPtr data);

static int
xmlSecGnuTLSAsymKeyDataInitialize(xmlSecKeyDataPtr data) {
Expand Down Expand Up @@ -247,7 +243,7 @@ xmlSecGnuTLSAsymKeyDataDuplicate(xmlSecKeyDataPtr dst, xmlSecKeyDataPtr src) {
return(0);
}

static gnutls_pubkey_t
gnutls_pubkey_t
xmlSecGnuTLSAsymKeyDataGetPublicKey(xmlSecKeyDataPtr data) {
xmlSecGnuTLSAsymKeyDataCtxPtr ctx;

Expand All @@ -260,7 +256,7 @@ xmlSecGnuTLSAsymKeyDataGetPublicKey(xmlSecKeyDataPtr data) {
return(ctx->pubkey);
}

static gnutls_privkey_t
gnutls_privkey_t
xmlSecGnuTLSAsymKeyDataGetPrivateKey(xmlSecKeyDataPtr data) {
xmlSecGnuTLSAsymKeyDataCtxPtr ctx;

Expand All @@ -273,7 +269,7 @@ xmlSecGnuTLSAsymKeyDataGetPrivateKey(xmlSecKeyDataPtr data) {
return(ctx->privkey);
}

static xmlSecKeyDataType
xmlSecKeyDataType
xmlSecGnuTLSAsymKeyDataGetType(xmlSecKeyDataPtr data) {
xmlSecGnuTLSAsymKeyDataCtxPtr ctx;

Expand All @@ -294,7 +290,7 @@ xmlSecGnuTLSAsymKeyDataGetType(xmlSecKeyDataPtr data) {
return (xmlSecKeyDataTypeUnknown);
}

static xmlSecSize
xmlSecSize
xmlSecGnuTLSAsymKeyDataGetSize(xmlSecKeyDataPtr data) {
xmlSecGnuTLSAsymKeyDataCtxPtr ctx;
unsigned int bits = 0;
Expand Down
4 changes: 4 additions & 0 deletions src/gnutls/private.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ xmlSecKeyDataPtr xmlSecGnuTLSAsymKeyDataCreate (gnutls_pubkey_t
gnutls_privkey_t privkey);


gnutls_pubkey_t xmlSecGnuTLSAsymKeyDataGetPublicKey (xmlSecKeyDataPtr data);
gnutls_privkey_t xmlSecGnuTLSAsymKeyDataGetPrivateKey (xmlSecKeyDataPtr data);
xmlSecKeyDataType xmlSecGnuTLSAsymKeyDataGetType (xmlSecKeyDataPtr data);
xmlSecSize xmlSecGnuTLSAsymKeyDataGetSize (xmlSecKeyDataPtr data);

#ifndef XMLSEC_NO_X509

Expand Down
2 changes: 1 addition & 1 deletion src/nss/app.c
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,7 @@ xmlSecNssAppKeyCertLoadSECItem(xmlSecKeyPtr key, SECItem* secItem, xmlSecKeyData
isKeyCert = 1;
}
}
if(isKeyCert) {
if(isKeyCert != 0) {
ret = xmlSecNssKeyDataX509AdoptKeyCert(x509Data, cert);
if(ret < 0) {
xmlSecInternalError("xmlSecNssKeyDataX509AdoptKeyCert", NULL);
Expand Down

0 comments on commit 7884d21

Please sign in to comment.