Skip to content

Commit

Permalink
(xmlsec-core) Added signature verification to the examples
Browse files Browse the repository at this point in the history
  • Loading branch information
lsh123 committed Jan 9, 2025
1 parent 516d5e6 commit bb54757
Show file tree
Hide file tree
Showing 10 changed files with 289 additions and 25 deletions.
4 changes: 2 additions & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ <h1>XML Security Library</h1>
<li>TBD<br>
The <a href="download.html">XML Security Library 1.3.7</a> release includes the following changes:
<ul>
<li>(xmlsec-core) Added XMLSEC_TRANSFORM_FLAGS_USER_SPECIFIED flag to the xmlSecTransform to differentiate transforms specified in the input XML file vs transforms automatically added by XMLSec library.
</li>
<li>(xmlsec-core) Added XMLSEC_TRANSFORM_FLAGS_USER_SPECIFIED flag to the xmlSecTransform to differentiate transforms specified in the input XML file vs transforms automatically added by XMLSec library.</li>
<li>(xmlsec-core) Added signature verification to the examples to demonstrate the need to ensure the correct data is actually signed.</li>
<li>(xmlsec-core) Disabled old crypto algorithms (MD5, RIPEMD160) and the old crypto engines (MSCrypto, GCrypt) by default (use "--with-legacy-features" option to reenable everything).</li>
<li>(xmlsec-windows) Disabled old crypto algorithms (MD5, RIPEMD160), made "mscng" the default crypto engine on Windows, and added support for "legacy-features" flag for "configure.js".<li>
<li>(xmlsec-openssl, xmlsec-gnutls, xmlsec-mscng) Added an option to skip timestamp checks for certificates and CLRs.</li>
Expand Down
22 changes: 17 additions & 5 deletions examples/Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
#
#
#
PROGRAMS_SIGN = sign1 sign2 sign3
PROGRAMS_VERIFY = verify1 verify2 verify3 verify4
PROGRAMS_ENC = encrypt1 encrypt2 encrypt3
PROGRAMS_DEC = decrypt1 decrypt2 decrypt3
PROGRAMS = \
sign1 sign2 sign3 \
verify1 verify2 verify3 verify4 \
encrypt1 encrypt2 encrypt3 \
decrypt1 decrypt2 decrypt3 \
$(PROGRAMS_SIGN) \
$(PROGRAMS_VERIFY) \
$(PROGRAMS_ENC) \
$(PROGRAMS_DEC) \
xmldsigverify

CC = gcc
Expand All @@ -17,19 +21,27 @@ all: $(PROGRAMS)
clean:
rm -rf $(PROGRAMS)

check: $(PROGRAMS)
check: check-sign check-verify check-enc check-dec

check-sign: $(PROGRAMS_SIGN)
./sign1 sign1-tmpl.xml rsakey.pem
./sign2 sign2-doc.xml rsakey.pem
./sign3 sign3-doc.xml rsakey.pem rsacert.pem

check-verify: $(PROGRAMS_VERIFY)
./verify1 sign1-res.xml rsapub.pem
./verify1 sign2-res.xml rsapub.pem
./verify2 sign1-res.xml rsakey.pem
./verify2 sign2-res.xml rsakey.pem
./verify3 sign3-res.xml ca2cert.pem cacert.pem
./verify4 verify4-res.xml ca2cert.pem cacert.pem

check-enc: $(PROGRAMS_ENC)
./encrypt1 encrypt1-tmpl.xml deskey.bin
./encrypt2 encrypt2-doc.xml deskey.bin
./encrypt3 encrypt3-doc.xml rsakey.pem

check-dec: $(PROGRAMS_DEC)
./decrypt1 encrypt1-res.xml deskey.bin
./decrypt1 encrypt2-res.xml deskey.bin
./decrypt2 encrypt1-res.xml deskey.bin
Expand Down
6 changes: 3 additions & 3 deletions examples/sign2-res.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ XML Security Library example: Original XML doc file for sign2 example.
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>HjY8ilZAIEM2tBbPn5mYO1ieIX4=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>GnYgZdzPeXd/gPTJmQ506qmxWkd3VK1Y23kh5Qpq8y4LMNY+LJJeCWK5wpo/vufR
nIH/KUqvIvtk9nb2IjF5Uw==</SignatureValue>
<SignatureValue>fUkinGC3hXEUrjJoq8Uc1Gtky7+4AumhtYV5804diUqbFh/SbQI5iPOnJojz0xZK
WFG9pbfsiWyiqTYlenqDng==</SignatureValue>
<KeyInfo>
<KeyName>rsakey.pem</KeyName>
</KeyInfo>
Expand Down
2 changes: 1 addition & 1 deletion examples/sign2.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ sign_file(const char* xml_file, const char* key_file) {

/* add reference */
refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformSha1Id,
NULL, NULL, NULL);
NULL, BAD_CAST "", NULL);
if(refNode == NULL) {
fprintf(stderr, "Error: failed to add reference to signature template\n");
goto done;
Expand Down
10 changes: 6 additions & 4 deletions examples/sign3-res.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,19 @@ XML Security Library example: Original XML doc file for sign3 example.
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>HjY8ilZAIEM2tBbPn5mYO1ieIX4=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>GnYgZdzPeXd/gPTJmQ506qmxWkd3VK1Y23kh5Qpq8y4LMNY+LJJeCWK5wpo/vufR
nIH/KUqvIvtk9nb2IjF5Uw==</SignatureValue>
<SignatureValue>fUkinGC3hXEUrjJoq8Uc1Gtky7+4AumhtYV5804diUqbFh/SbQI5iPOnJojz0xZK
WFG9pbfsiWyiqTYlenqDng==</SignatureValue>
<KeyInfo>
<X509Data>
<X509SubjectName>[email protected],CN=Aleksey Sanin,OU=Test Third Level RSA Certificate,O=XML Security Library (http://www.aleksey.com/xmlsec),ST=California,C=US</X509SubjectName>
<X509Certificate>MIIDpzCCA1GgAwIBAgIJAK+ii7kzrdqvMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTE9MDsGA1UEChM0WE1MIFNlY3Vy
aXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2VjKTEWMBQG
Expand All @@ -41,7 +42,8 @@ IFNlY3VyaXR5IExpYnJhcnkgKGh0dHA6Ly93d3cuYWxla3NleS5jb20veG1sc2Vj
KTEQMA4GA1UECxMHUm9vdCBDQTEWMBQGA1UEAxMNQWxla3NleSBTYW5pbjEhMB8G
CSqGSIb3DQEJARYSeG1sc2VjQGFsZWtzZXkuY29tggkAr6KLuTOt2q0wDQYJKoZI
hvcNAQEFBQADQQAOXBj0yICp1RmHXqnUlsppryLCW3pKBD1dkb4HWarO7RjA1yJJ
fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga</X509Certificate>
fBjXssrERn05kpBcrRfzou4r3DCgQFPhjxga
</X509Certificate>
</X509Data>
</KeyInfo>
</Signature></Envelope>
2 changes: 1 addition & 1 deletion examples/sign3.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ sign_file(const char* xml_file, const char* key_file, const char* cert_file) {

/* add reference */
refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformSha1Id,
NULL, NULL, NULL);
NULL, BAD_CAST "", NULL);
if(refNode == NULL) {
fprintf(stderr, "Error: failed to add reference to signature template\n");
goto done;
Expand Down
69 changes: 66 additions & 3 deletions examples/verify1.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <xmlsec/crypto.h>

int verify_file(const char* xml_file, const char* key_file);
int verify_signature_results(xmlSecDSigCtxPtr dsigCtx);

int
main(int argc, char **argv) {
Expand Down Expand Up @@ -186,12 +187,12 @@ verify_file(const char* xml_file, const char* key_file) {

/* Verify signature */
if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
fprintf(stderr,"Error: signature verify\n");
fprintf(stderr,"Error: signature verificaton failed\n");
goto done;
}

/* print verification result to stdout */
if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
/* verif results and print outcome to stdout */
if(verify_signature_results(dsigCtx) == 0) {
fprintf(stdout, "Signature is OK\n");
} else {
fprintf(stdout, "Signature is INVALID\n");
Expand All @@ -211,3 +212,65 @@ verify_file(const char* xml_file, const char* key_file) {
}
return(res);
}

/**
* verify_signature_results:
* @dsigCtx: the XMLDSig context
*
* Verifies XML signature results to ensure that signature was applied
* to the expected data.
*
* Returns 0 on success or a negative value if an error occurs.
*/
int
verify_signature_results(xmlSecDSigCtxPtr dsigCtx) {
xmlSecDSigReferenceCtxPtr dsigRefCtx;
xmlSecTransformPtr transform;

assert(dsigCtx);

/* check that signature verification succeeded */
if(dsigCtx->status != xmlSecDSigStatusSucceeded) {
fprintf(stderr,"Error: Signature verificaton result is not SUCCESS\n");
return(-1);
}

/* in this example we expect exactly ONE reference with URI="" and
* exactly ONE enveloped signature transform (i.e. the whole document is signed)*/
if(xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences)) != 1) {
fprintf(stderr,"Error: Exactly one Reference is expected\n");
return(-1);
}
dsigRefCtx = (xmlSecDSigReferenceCtxPtr)xmlSecPtrListGetItem(&(dsigCtx->signedInfoReferences), 0);
if((dsigRefCtx == NULL) || (dsigRefCtx->status != xmlSecDSigStatusSucceeded)) {
fprintf(stderr,"Error: Reference verification result is not SUCCESS\n");
return(-1);
}

/* check URI */
if(!xmlStrEqual(dsigRefCtx->uri, BAD_CAST "")) {
fprintf(stderr,"Error: Reference URI value doesn't match expected one\n");
return(-1);
}

/* check transforms: we expect only one "enveloped signature" transform */
transform = dsigRefCtx->transformCtx.first;
if((transform == NULL) || (!xmlStrEqual(transform->id->name, xmlSecNameEnveloped))) {
fprintf(stderr,"Error: First Transform name '%s' doesn't match expected '%s'\n", (transform != NULL ? transform->id->name : BAD_CAST "NULL"), xmlSecNameEnveloped);
return(-1);
}

/* all other transforms should be inserted by XMLSec */
transform = transform->next;
while(transform != NULL) {
if((transform->flags & XMLSEC_TRANSFORM_FLAGS_USER_SPECIFIED) != 0) {
fprintf(stderr,"Error: Found unexpected Transform name '%s'\n", transform->id->name);
return(-1);
}
transform = transform->next;
}

/* all good! */
return(0);
}

67 changes: 65 additions & 2 deletions examples/verify2.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

xmlSecKeysMngrPtr load_keys(char** files, int files_size);
int verify_file(xmlSecKeysMngrPtr mngr, const char* xml_file);
int verify_signature_results(xmlSecDSigCtxPtr dsigCtx);

int
main(int argc, char **argv) {
Expand Down Expand Up @@ -260,8 +261,8 @@ verify_file(xmlSecKeysMngrPtr mngr, const char* xml_file) {
goto done;
}

/* print verification result to stdout */
if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
/* verif results and print outcome to stdout */
if(verify_signature_results(dsigCtx) == 0) {
fprintf(stdout, "Signature is OK\n");
} else {
fprintf(stdout, "Signature is INVALID\n");
Expand All @@ -281,3 +282,65 @@ verify_file(xmlSecKeysMngrPtr mngr, const char* xml_file) {
}
return(res);
}


/**
* verify_signature_results:
* @dsigCtx: the XMLDSig context
*
* Verifies XML signature results to ensure that signature was applied
* to the expected data.
*
* Returns 0 on success or a negative value if an error occurs.
*/
int
verify_signature_results(xmlSecDSigCtxPtr dsigCtx) {
xmlSecDSigReferenceCtxPtr dsigRefCtx;
xmlSecTransformPtr transform;

assert(dsigCtx);

/* check that signature verification succeeded */
if(dsigCtx->status != xmlSecDSigStatusSucceeded) {
fprintf(stderr,"Error: Signature verificaton result is not SUCCESS\n");
return(-1);
}

/* in this example we expect exactly ONE reference with URI="" and
* exactly ONE enveloped signature transform (i.e. the whole document is signed)*/
if(xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences)) != 1) {
fprintf(stderr,"Error: Exactly one Reference is expected\n");
return(-1);
}
dsigRefCtx = (xmlSecDSigReferenceCtxPtr)xmlSecPtrListGetItem(&(dsigCtx->signedInfoReferences), 0);
if((dsigRefCtx == NULL) || (dsigRefCtx->status != xmlSecDSigStatusSucceeded)) {
fprintf(stderr,"Error: Reference verification result is not SUCCESS\n");
return(-1);
}

/* check URI */
if(!xmlStrEqual(dsigRefCtx->uri, BAD_CAST "")) {
fprintf(stderr,"Error: Reference URI value doesn't match expected one\n");
return(-1);
}

/* check transforms: we expect only one "enveloped signature" transform */
transform = dsigRefCtx->transformCtx.first;
if((transform == NULL) || (!xmlStrEqual(transform->id->name, xmlSecNameEnveloped))) {
fprintf(stderr,"Error: First Transform name '%s' doesn't match expected '%s'\n", (transform != NULL ? transform->id->name : BAD_CAST "NULL"), xmlSecNameEnveloped);
return(-1);
}

/* all other transforms should be inserted by XMLSec */
transform = transform->next;
while(transform != NULL) {
if((transform->flags & XMLSEC_TRANSFORM_FLAGS_USER_SPECIFIED) != 0) {
fprintf(stderr,"Error: Found unexpected Transform name '%s'\n", transform->id->name);
return(-1);
}
transform = transform->next;
}

/* all good! */
return(0);
}
65 changes: 63 additions & 2 deletions examples/verify3.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

xmlSecKeysMngrPtr load_trusted_certs(char** files, int files_size);
int verify_file(xmlSecKeysMngrPtr mngr, const char* xml_file);
int verify_signature_results(xmlSecDSigCtxPtr dsigCtx);

int
main(int argc, char **argv) {
Expand Down Expand Up @@ -241,8 +242,8 @@ verify_file(xmlSecKeysMngrPtr mngr, const char* xml_file) {
goto done;
}

/* print verification result to stdout */
if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
/* verif results and print outcome to stdout */
if(verify_signature_results(dsigCtx) == 0) {
fprintf(stdout, "Signature is OK\n");
} else {
fprintf(stdout, "Signature is INVALID\n");
Expand All @@ -263,4 +264,64 @@ verify_file(xmlSecKeysMngrPtr mngr, const char* xml_file) {
return(res);
}

/**
* verify_signature_results:
* @dsigCtx: the XMLDSig context
*
* Verifies XML signature results to ensure that signature was applied
* to the expected data.
*
* Returns 0 on success or a negative value if an error occurs.
*/
int
verify_signature_results(xmlSecDSigCtxPtr dsigCtx) {
xmlSecDSigReferenceCtxPtr dsigRefCtx;
xmlSecTransformPtr transform;

assert(dsigCtx);

/* check that signature verification succeeded */
if(dsigCtx->status != xmlSecDSigStatusSucceeded) {
fprintf(stderr,"Error: Signature verificaton result is not SUCCESS\n");
return(-1);
}

/* in this example we expect exactly ONE reference with URI="" and
* exactly ONE enveloped signature transform (i.e. the whole document is signed)*/
if(xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences)) != 1) {
fprintf(stderr,"Error: Exactly one Reference is expected\n");
return(-1);
}
dsigRefCtx = (xmlSecDSigReferenceCtxPtr)xmlSecPtrListGetItem(&(dsigCtx->signedInfoReferences), 0);
if((dsigRefCtx == NULL) || (dsigRefCtx->status != xmlSecDSigStatusSucceeded)) {
fprintf(stderr,"Error: Reference verification result is not SUCCESS\n");
return(-1);
}

/* check URI */
if(!xmlStrEqual(dsigRefCtx->uri, BAD_CAST "")) {
fprintf(stderr,"Error: Reference URI value doesn't match expected one\n");
return(-1);
}

/* check transforms: we expect only one "enveloped signature" transform */
transform = dsigRefCtx->transformCtx.first;
if((transform == NULL) || (!xmlStrEqual(transform->id->name, xmlSecNameEnveloped))) {
fprintf(stderr,"Error: First Transform name '%s' doesn't match expected '%s'\n", (transform != NULL ? transform->id->name : BAD_CAST "NULL"), xmlSecNameEnveloped);
return(-1);
}

/* all other transforms should be inserted by XMLSec */
transform = transform->next;
while(transform != NULL) {
if((transform->flags & XMLSEC_TRANSFORM_FLAGS_USER_SPECIFIED) != 0) {
fprintf(stderr,"Error: Found unexpected Transform name '%s'\n", transform->id->name);
return(-1);
}
transform = transform->next;
}

/* all good! */
return(0);
}

Loading

0 comments on commit bb54757

Please sign in to comment.