diff options
Diffstat (limited to 'src/openssl/signatures.c')
-rw-r--r-- | src/openssl/signatures.c | 508 |
1 files changed, 168 insertions, 340 deletions
diff --git a/src/openssl/signatures.c b/src/openssl/signatures.c index d10204de..bc695f42 100644 --- a/src/openssl/signatures.c +++ b/src/openssl/signatures.c @@ -1,15 +1,24 @@ -/** - * XMLSec library +/* + * XML Security Library (http://www.aleksey.com/xmlsec). + * * * This is free software; see Copyright file in the source * distribution for preciese wording. * * Copyright (C) 2002-2016 Aleksey Sanin <aleksey@aleksey.com>. All Rights Reserved. */ +/** + * SECTION:signatures + * @Short_description: Signatures implementation for OpenSSL. + * @Stability: Private + * + */ + #include "globals.h" #include <string.h> +#include <openssl/bn.h> #include <openssl/evp.h> #include <openssl/rand.h> #include <openssl/sha.h> @@ -21,55 +30,72 @@ #include <xmlsec/openssl/crypto.h> #include <xmlsec/openssl/evp.h> +#include "openssl_compat.h" -/* new API from OpenSSL 1.1.0 (https://www.openssl.org/docs/manmaster/crypto/EVP_DigestInit.html): +/****************************************************************************** * - * EVP_MD_CTX_create() and EVP_MD_CTX_destroy() were renamed to EVP_MD_CTX_new() and EVP_MD_CTX_free() in OpenSSL 1.1. - */ -#if !defined(XMLSEC_OPENSSL_110) -#define EVP_MD_CTX_new() EVP_MD_CTX_create() -#define EVP_MD_CTX_free(x) EVP_MD_CTX_destroy((x)) -#define EVP_MD_CTX_md_data(x) ((x)->md_data) + * OpenSSL 1.1.0 compatibility + * + *****************************************************************************/ +#if !defined(XMLSEC_OPENSSL_API_110) -#ifndef XMLSEC_NO_DSA -/* we expect the r/s to be NOT NULL */ -static void ECDSA_SIG_get0(BIGNUM **pr, BIGNUM **ps, ECDSA_SIG *sig) { - if (pr != NULL) { - if(sig->r == NULL) { - sig->r = BN_new(); - } - *pr = sig->r; +#ifndef XMLSEC_NO_ECDSA + +static inline void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) { + xmlSecAssert(sig != NULL); + + if(pr != NULL) { + (*pr) = sig->r; } - if (ps != NULL) { - if(sig->s == NULL) { - sig->s = BN_new(); - } - *ps = sig->s; + if(ps != NULL) { + (*ps) = sig->s; } } -#endif /* XMLSEC_NO_ECDSA */ -#endif /* !defined(XMLSEC_OPENSSL_110) */ +static inline int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) { + xmlSecAssert2(sig != NULL, 0); + + if((r == NULL) || (s == NULL)) { + return(0); + } + BN_clear_free(sig->r); + BN_clear_free(sig->s); + sig->r = r; + sig->s = s; + return(1); +} +#endif /* XMLSEC_NO_ECDSA */ -/* Preparation for OpenSSL 1.1.0 compatibility: we expect the r/s to be NOT NULL */ #ifndef XMLSEC_NO_DSA -static void DSA_SIG_get0(BIGNUM **pr, BIGNUM **ps, DSA_SIG *sig) { - if (pr != NULL) { - if(sig->r == NULL) { - sig->r = BN_new(); - } - *pr = sig->r; + +static inline void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) { + xmlSecAssert(sig != NULL); + + if(pr != NULL) { + (*pr) = sig->r; } - if (ps != NULL) { - if(sig->s == NULL) { - sig->s = BN_new(); - } - *ps = sig->s; + if(ps != NULL) { + (*ps) = sig->s; } } -#endif /* XMLSEC_NO_DSA */ +static inline int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) { + xmlSecAssert2(sig != NULL, 0); + + if(r == NULL || s == NULL) { + return(0); + } + BN_clear_free(sig->r); + BN_clear_free(sig->s); + + sig->r = r; + sig->s = s; + return(1); +} +#endif /* XMLSEC_NO_DSA */ + +#endif /* !defined(XMLSEC_OPENSSL_API_110) */ /************************************************************************** @@ -214,8 +240,6 @@ xmlSecOpenSSLSignatureCheckId(xmlSecTransformPtr transform) { { return(0); } - - return(0); } static int @@ -303,32 +327,22 @@ xmlSecOpenSSLSignatureInitialize(xmlSecTransformPtr transform) { #endif /* XMLSEC_NO_ECDSA */ if(1) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_TRANSFORM, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInvalidTransfromError(transform) return(-1); } /* create/init digest CTX */ ctx->digestCtx = EVP_MD_CTX_new(); if(ctx->digestCtx == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "EVP_MD_CTX_new", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("EVP_MD_CTX_new", + xmlSecTransformGetName(transform)); return(-1); } ret = EVP_DigestInit(ctx->digestCtx, ctx->digest); if(ret != 1) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "EVP_DigestInit", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("EVP_DigestInit", + xmlSecTransformGetName(transform)); return(-1); } @@ -379,11 +393,8 @@ xmlSecOpenSSLSignatureSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { pKey = xmlSecOpenSSLEvpKeyDataGetEvp(value); if(pKey == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecOpenSSLEvpKeyDataGetEvp", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInternalError("xmlSecOpenSSLEvpKeyDataGetEvp", + xmlSecTransformGetName(transform)); return(-1); } @@ -393,11 +404,8 @@ xmlSecOpenSSLSignatureSetKey(xmlSecTransformPtr transform, xmlSecKeyPtr key) { ctx->pKey = xmlSecOpenSSLEvpKeyDup(pKey); if(ctx->pKey == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecOpenSSLEvpKeyDup", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInternalError("xmlSecOpenSSLEvpKeyDup", + xmlSecTransformGetName(transform)); return(-1); } @@ -450,11 +458,8 @@ xmlSecOpenSSLSignatureVerify(xmlSecTransformPtr transform, ret = (ctx->verifyCallback)(ctx, data, dataSize); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "verifyCallback", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInternalError("verifyCallback", + xmlSecTransformGetName(transform)); return(-1); } @@ -462,11 +467,9 @@ xmlSecOpenSSLSignatureVerify(xmlSecTransformPtr transform, if(ret == 1) { transform->status = xmlSecTransformStatusOk; } else { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "verifyCallback", - XMLSEC_ERRORS_R_DATA_NOT_MATCH, - "signature do not match"); + xmlSecOtherError(XMLSEC_ERRORS_R_DATA_NOT_MATCH, + xmlSecTransformGetName(transform), + "ctx->verifyCallback: signature does not verify"); transform->status = xmlSecTransformStatusFail; } @@ -513,21 +516,15 @@ xmlSecOpenSSLSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTran ret = EVP_DigestUpdate(ctx->digestCtx, xmlSecBufferGetData(in), inSize); if(ret != 1) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "EVP_DigestUpdate", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("EVP_DigestUpdate", + xmlSecTransformGetName(transform)); return(-1); } ret = xmlSecBufferRemoveHead(in, inSize); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "xmlSecBufferRemoveHead", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInternalError("xmlSecBufferRemoveHead", + xmlSecTransformGetName(transform)); return(-1); } } @@ -537,11 +534,8 @@ xmlSecOpenSSLSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTran ret = EVP_DigestFinal(ctx->digestCtx, ctx->dgst, &ctx->dgstSize); if(ret != 1) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "EVP_DigestFinal", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("EVP_DigestFinal", + xmlSecTransformGetName(transform)); return(-1); } xmlSecAssert2(ctx->dgstSize > 0, -1); @@ -550,11 +544,8 @@ xmlSecOpenSSLSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTran if(transform->operation == xmlSecTransformOperationSign) { ret = (ctx->signCallback)(ctx, out); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - "signCallback", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInternalError("signCallback", + xmlSecTransformGetName(transform)); return(-1); } } @@ -567,11 +558,7 @@ xmlSecOpenSSLSignatureExecute(xmlSecTransformPtr transform, int last, xmlSecTran /* the only way we can get here is if there is no input */ xmlSecAssert2(xmlSecBufferGetSize(&(transform->inBuf)) == 0, -1); } else { - xmlSecError(XMLSEC_ERRORS_HERE, - xmlSecErrorsSafeString(xmlSecTransformGetName(transform)), - NULL, - XMLSEC_ERRORS_R_INVALID_STATUS, - "status=%d", transform->status); + xmlSecInvalidTransfromStatusError(transform); return(-1); } @@ -610,7 +597,7 @@ static int xmlSecOpenSSLSignatureDsaSign(xmlSecOpenSSLSignatureCtxPtr ctx, xmlSecBufferPtr out) { DSA * dsaKey = NULL; DSA_SIG *sig = NULL; - BIGNUM *rr = NULL, *ss = NULL; + const BIGNUM *rr = NULL, *ss = NULL; xmlSecByte *outData; xmlSecSize dsaSignSize, signHalfSize, rSize, sSize; int res = -1; @@ -625,85 +612,54 @@ xmlSecOpenSSLSignatureDsaSign(xmlSecOpenSSLSignatureCtxPtr ctx, xmlSecBufferPtr /* get key */ dsaKey = EVP_PKEY_get1_DSA(ctx->pKey); if(dsaKey == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "EVP_PKEY_get1_DSA", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("EVP_PKEY_get1_DSA", NULL); goto done; } /* signature size = r + s + 8 bytes, we just need r+s */ dsaSignSize = DSA_size(dsaKey); if(dsaSignSize < 8) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "DSA_size", - XMLSEC_ERRORS_R_INVALID_SIZE, - "dsaSignSize=%d", (int)dsaSignSize); + xmlSecInvalidSizeLessThanError("DSA signature", dsaSignSize, 8, NULL); goto done; } signHalfSize = (dsaSignSize - 8) / 2; if(signHalfSize < 4) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "signHalfSize", - XMLSEC_ERRORS_R_INVALID_SIZE, - "signHalfSize=%d", (int)signHalfSize); + xmlSecInvalidSizeLessThanError("DSA signature (half)", signHalfSize, 4, NULL); goto done; } /* calculate signature */ sig = DSA_do_sign(ctx->dgst, ctx->dgstSize, dsaKey); if(sig == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "DSA_do_sign", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("DSA_do_sign", NULL); goto done; } /* get signature components */ - DSA_SIG_get0(&rr, &ss, sig); + DSA_SIG_get0(sig, &rr, &ss); if((rr == NULL) || (ss == NULL)) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "DSA_SIG_get0", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("DSA_SIG_get0", NULL); goto done; } rSize = BN_num_bytes(rr); if(rSize > signHalfSize) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_INVALID_SIZE, - "rSize=%d > %d", - rSize, signHalfSize); + xmlSecInvalidSizeMoreThanError("DSA signature r", + rSize, signHalfSize, NULL); goto done; } sSize = BN_num_bytes(ss); if(sSize > signHalfSize) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_INVALID_SIZE, - "sSize=%d > %d", - sSize, signHalfSize); + xmlSecInvalidSizeMoreThanError("DSA signature s", + sSize, signHalfSize, NULL); goto done; } /* allocate buffer */ ret = xmlSecBufferSetSize(out, 2 * signHalfSize); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecBufferSetSize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", (int)(2 * signHalfSize)); + xmlSecInternalError2("xmlSecBufferSetSize", NULL, + "size=%d", (int)(2 * signHalfSize)); goto done; } outData = xmlSecBufferGetData(out); @@ -726,12 +682,6 @@ done: if(dsaKey != NULL) { DSA_free(dsaKey); } - if(rr != NULL) { - BN_free(rr); - } - if(ss != NULL) { - BN_free(ss); - } /* done */ return(res); @@ -754,95 +704,63 @@ xmlSecOpenSSLSignatureDsaVerify(xmlSecOpenSSLSignatureCtxPtr ctx, const xmlSecBy /* get key */ dsaKey = EVP_PKEY_get1_DSA(ctx->pKey); if(dsaKey == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "EVP_PKEY_get1_DSA", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("EVP_PKEY_get1_DSA", NULL); goto done; } /* signature size = r + s + 8 bytes, we just need r+s */ dsaSignSize = DSA_size(dsaKey); if(dsaSignSize < 8) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "DSA_size", - XMLSEC_ERRORS_R_INVALID_SIZE, - "dsaSignSize=%d", (int)dsaSignSize); + xmlSecInvalidSizeLessThanError("DSA signatue", + dsaSignSize, 8, NULL); goto done; } signHalfSize = (dsaSignSize - 8) / 2; if(signHalfSize < 4) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "signHalfSize", - XMLSEC_ERRORS_R_INVALID_SIZE, - "signHalfSize=%d", (int)signHalfSize); + xmlSecInvalidSizeLessThanError("DSA signatue (half size)", + signHalfSize, 4, NULL); goto done; } /* check size */ if(signSize != 2 * signHalfSize) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_INVALID_SIZE, - "invalid length %d (%d expected)", - (int)signSize, (int)(2 * signHalfSize)); + xmlSecInvalidSizeError("DSA signature", signSize, 2 * signHalfSize, + NULL); goto done; } /* create/read signature */ sig = DSA_SIG_new(); if (sig == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "DSA_SIG_new", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("DSA_SIG_new", NULL); goto done; } - /* get signature components */ - DSA_SIG_get0(&rr, &ss, sig); - if((rr == NULL) || (ss == NULL)) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "DSA_SIG_get0", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - goto done; - } - - rr = BN_bin2bn(signData, signHalfSize, rr); + rr = BN_bin2bn(signData, signHalfSize, NULL); if(rr == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "BN_bin2bn(sig->r)", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("BN_bin2bn(sig->r)", NULL); goto done; } - ss = BN_bin2bn(signData + signHalfSize, signHalfSize, ss); + ss = BN_bin2bn(signData + signHalfSize, signHalfSize, NULL); if(ss == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "BN_bin2bn(sig->s)", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("BN_bin2bn(sig->s)", NULL); + goto done; + } + + ret = DSA_SIG_set0(sig, rr, ss); + if(ret == 0) { + xmlSecOpenSSLError("DSA_SIG_set0", NULL); goto done; } + rr = NULL; + ss = NULL; + /* verify signature */ ret = DSA_do_verify(ctx->dgst, ctx->dgstSize, sig, dsaKey); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "DSA_do_verify", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("DSA_do_verify", NULL); goto done; } @@ -855,19 +773,10 @@ xmlSecOpenSSLSignatureDsaVerify(xmlSecOpenSSLSignatureCtxPtr ctx, const xmlSecBy done: /* cleanup */ - if(sig != NULL) { - DSA_SIG_free(sig); - } - if(dsaKey != NULL) { - DSA_free(dsaKey); - } - if(rr != NULL) { - BN_free(rr); - } - if(ss != NULL) { - BN_free(ss); - } - + DSA_SIG_free(sig); + DSA_free(dsaKey); + BN_clear_free(rr); + BN_clear_free(ss); /* done */ return(res); } @@ -1000,30 +909,18 @@ xmlSecOpenSSLSignatureEcdsaSignatureHalfSize(EC_KEY * ecKey) { group = EC_KEY_get0_group(ecKey); if(group == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "EC_KEY_get0_group", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("EC_KEY_get0_group", NULL); goto done; } order = BN_new(); if(order == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "BN_new", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("BN_new", NULL); goto done; } if(EC_GROUP_get_order(group, order, NULL) != 1) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "EC_GROUP_get_order", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("EC_GROUP_get_order", NULL); goto done; } @@ -1045,7 +942,7 @@ static int xmlSecOpenSSLSignatureEcdsaSign(xmlSecOpenSSLSignatureCtxPtr ctx, xmlSecBufferPtr out) { EC_KEY * ecKey = NULL; ECDSA_SIG *sig = NULL; - BIGNUM *rr = NULL, *ss = NULL; + const BIGNUM *rr = NULL, *ss = NULL; xmlSecByte *outData; xmlSecSize signHalfSize, rSize, sSize; int res = -1; @@ -1060,78 +957,51 @@ xmlSecOpenSSLSignatureEcdsaSign(xmlSecOpenSSLSignatureCtxPtr ctx, xmlSecBufferPt /* get key */ ecKey = EVP_PKEY_get1_EC_KEY(ctx->pKey); if(ecKey == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "EVP_PKEY_get1_DSA", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("EVP_PKEY_get1_DSA", NULL); goto done; } /* calculate signature size */ signHalfSize = xmlSecOpenSSLSignatureEcdsaSignatureHalfSize(ecKey); if(signHalfSize <= 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecOpenSSLSignatureEcdsaSignatureHalfSize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInternalError("xmlSecOpenSSLSignatureEcdsaSignatureHalfSize", NULL); goto done; } /* sign */ sig = ECDSA_do_sign(ctx->dgst, ctx->dgstSize, ecKey); if(sig == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "ECDSA_do_sign", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("ECDSA_do_sign", NULL); goto done; } /* get signature components */ - ECDSA_SIG_get0(&rr, &ss, sig); + ECDSA_SIG_get0(sig, &rr, &ss); if((rr == NULL) || (ss == NULL)) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "ECDSA_SIG_get0", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("ECDSA_SIG_get0", NULL); goto done; } /* check sizes */ rSize = BN_num_bytes(rr); if(rSize > signHalfSize) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_INVALID_SIZE, - "rSize=%d > %d", - (int)rSize, (int)signHalfSize); + xmlSecInvalidSizeMoreThanError("ECDSA signatue r", + rSize, signHalfSize, NULL); goto done; } sSize = BN_num_bytes(ss); if(sSize > signHalfSize) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_INVALID_SIZE, - "sSize=%d > %d", - (int)sSize, (int)signHalfSize); + xmlSecInvalidSizeMoreThanError("ECDSA signatue s", + sSize, signHalfSize, NULL); goto done; } /* allocate buffer */ ret = xmlSecBufferSetSize(out, 2 * signHalfSize); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecBufferSetSize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "size=%d", (int)(2 * signHalfSize)); + xmlSecInternalError2("xmlSecBufferSetSize", NULL, + "size=%d", (int)(2 * signHalfSize)); goto done; } outData = xmlSecBufferGetData(out); @@ -1154,12 +1024,6 @@ done: if(ecKey != NULL) { EC_KEY_free(ecKey); } - if(rr != NULL) { - BN_free(rr); - } - if(ss != NULL) { - BN_free(ss); - } /* done */ return(res); @@ -1183,85 +1047,58 @@ xmlSecOpenSSLSignatureEcdsaVerify(xmlSecOpenSSLSignatureCtxPtr ctx, const xmlSec /* get key */ ecKey = EVP_PKEY_get1_EC_KEY(ctx->pKey); if(ecKey == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "EVP_PKEY_get1_DSA", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("EVP_PKEY_get1_EC_KEY", NULL); goto done; } /* calculate signature size */ signHalfSize = xmlSecOpenSSLSignatureEcdsaSignatureHalfSize(ecKey); if(signHalfSize <= 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecOpenSSLSignatureEcdsaSignatureHalfSize", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecInternalError("xmlSecOpenSSLSignatureEcdsaSignatureHalfSize", NULL); goto done; } - /* check size */ - if(signSize != 2 * signHalfSize) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_R_INVALID_SIZE, - "invalid length %d (%d expected)", - (int)signSize, (int)(2 * signHalfSize)); + /* check size: we expect the r and s to be the same size and match the size of + * the key (RFC 6931); however some implementations (e.g. Java) cut leading zeros: + * https://github.com/lsh123/xmlsec/issues/228 */ + if((signSize < 2 * signHalfSize) && (signSize % 2 == 0)) { + signHalfSize = signSize / 2; + } else if(signSize != 2 * signHalfSize) { + xmlSecInvalidSizeError("ECDSA signature", signSize, 2 * signHalfSize, + NULL); goto done; } /* create/read signature */ sig = ECDSA_SIG_new(); if (sig == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "DSA_SIG_new", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); - goto done; - } - - /* get signature components */ - ECDSA_SIG_get0(&rr, &ss, sig); - if((rr == NULL) || (ss == NULL)) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "ECDSA_SIG_get0", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("DSA_SIG_new", NULL); goto done; } - rr = BN_bin2bn(signData, signHalfSize, rr); + rr = BN_bin2bn(signData, signHalfSize, NULL); if(rr == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "BN_bin2bn(sig->r)", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("BN_bin2bn(sig->r)", NULL); goto done; } - ss = BN_bin2bn(signData + signHalfSize, signHalfSize, ss); + ss = BN_bin2bn(signData + signHalfSize, signHalfSize, NULL); if(ss == NULL) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "BN_bin2bn(sig->s)", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("BN_bin2bn(sig->s)", NULL); + goto done; + } + + ret = ECDSA_SIG_set0(sig, rr, ss); + if(ret == 0) { + xmlSecOpenSSLError("ECDSA_SIG_set0()", NULL); goto done; } + rr = NULL; + ss = NULL; /* verify signature */ ret = ECDSA_do_verify(ctx->dgst, ctx->dgstSize, sig, ecKey); if(ret < 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "ECDSA_do_verify", - XMLSEC_ERRORS_R_CRYPTO_FAILED, - XMLSEC_ERRORS_NO_MESSAGE); + xmlSecOpenSSLError("ECDSA_do_verify", NULL); goto done; } @@ -1274,19 +1111,10 @@ xmlSecOpenSSLSignatureEcdsaVerify(xmlSecOpenSSLSignatureCtxPtr ctx, const xmlSec done: /* cleanup */ - if(sig != NULL) { - ECDSA_SIG_free(sig); - } - if(ecKey != NULL) { - EC_KEY_free(ecKey); - } - if(rr != NULL) { - BN_free(rr); - } - if(ss != NULL) { - BN_free(ss); - } - + ECDSA_SIG_free(sig); + EC_KEY_free(ecKey); + BN_clear_free(rr); + BN_clear_free(ss); /* done */ return(res); } |