summaryrefslogtreecommitdiff
path: root/src/openssl/signatures.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openssl/signatures.c')
-rw-r--r--src/openssl/signatures.c508
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);
}