summaryrefslogtreecommitdiffstats
path: root/src/crypto/evp
diff options
context:
space:
mode:
authorAdam Langley <agl@google.com>2015-05-11 17:20:37 -0700
committerKenny Root <kroot@google.com>2015-05-12 23:06:14 +0000
commite9ada863a7b3e81f5d2b1e3bdd2305da902a87f5 (patch)
tree6e43e34595ecf887c26c32b86d8ab097fe8cac64 /src/crypto/evp
parentb3106a0cc1493bbe0505c0ec0ce3da4ca90a29ae (diff)
downloadexternal_boringssl-e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5.zip
external_boringssl-e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5.tar.gz
external_boringssl-e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5.tar.bz2
external/boringssl: bump revision.
This change bumps the BoringSSL revision to the current tip-of-tree. Change-Id: I91d5bf467e16e8d86cb19a4de873985f524e5faa
Diffstat (limited to 'src/crypto/evp')
-rw-r--r--src/crypto/evp/CMakeLists.txt14
-rw-r--r--src/crypto/evp/asn1.c2
-rw-r--r--src/crypto/evp/digestsign.c35
-rw-r--r--src/crypto/evp/evp.c42
-rw-r--r--src/crypto/evp/evp_ctx.c41
-rw-r--r--src/crypto/evp/evp_error.c131
-rw-r--r--src/crypto/evp/evp_extra_test.cc (renamed from src/crypto/evp/evp_test.c)524
-rw-r--r--src/crypto/evp/evp_test.cc262
-rw-r--r--src/crypto/evp/evp_tests.txt174
-rw-r--r--src/crypto/evp/internal.h43
-rw-r--r--src/crypto/evp/p_dsa_asn1.c569
-rw-r--r--src/crypto/evp/p_ec.c10
-rw-r--r--src/crypto/evp/p_ec_asn1.c65
-rw-r--r--src/crypto/evp/p_hmac.c3
-rw-r--r--src/crypto/evp/p_rsa.c65
-rw-r--r--src/crypto/evp/p_rsa_asn1.c42
-rw-r--r--src/crypto/evp/pbkdf_test.cc179
-rw-r--r--src/crypto/evp/sign.c10
18 files changed, 1629 insertions, 582 deletions
diff --git a/src/crypto/evp/CMakeLists.txt b/src/crypto/evp/CMakeLists.txt
index 9854a18..6db9752 100644
--- a/src/crypto/evp/CMakeLists.txt
+++ b/src/crypto/evp/CMakeLists.txt
@@ -10,7 +10,7 @@ add_library(
digestsign.c
evp.c
evp_ctx.c
- evp_error.c
+ p_dsa_asn1.c
p_ec.c
p_ec_asn1.c
p_hmac.c
@@ -23,16 +23,24 @@ add_library(
add_executable(
+ evp_extra_test
+
+ evp_extra_test.cc
+)
+
+add_executable(
evp_test
- evp_test.c
+ evp_test.cc
+ $<TARGET_OBJECTS:test_support>
)
add_executable(
pbkdf_test
- pbkdf_test.c
+ pbkdf_test.cc
)
+target_link_libraries(evp_extra_test crypto)
target_link_libraries(evp_test crypto)
target_link_libraries(pbkdf_test crypto)
diff --git a/src/crypto/evp/asn1.c b/src/crypto/evp/asn1.c
index 27ae017..3df9f52 100644
--- a/src/crypto/evp/asn1.c
+++ b/src/crypto/evp/asn1.c
@@ -105,7 +105,7 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
return ret;
err:
- if (ret != NULL && (out == NULL || *out != ret)) {
+ if (out == NULL || *out != ret) {
EVP_PKEY_free(ret);
}
return NULL;
diff --git a/src/crypto/evp/digestsign.c b/src/crypto/evp/digestsign.c
index c86b805..c163d40 100644
--- a/src/crypto/evp/digestsign.c
+++ b/src/crypto/evp/digestsign.c
@@ -65,9 +65,8 @@
/* md_begin_digset is a callback from the |EVP_MD_CTX| code that is called when
* a new digest is begun. */
static int md_begin_digest(EVP_MD_CTX *ctx) {
- int r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
- EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
- return r > 0 || r == -2;
+ return EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
+ EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
}
static const struct evp_md_pctx_ops md_pctx_ops = {
@@ -98,24 +97,24 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
if (is_verify) {
if (ctx->pctx->pmeth->verifyctx_init) {
- if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0) {
+ if (!ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx)) {
return 0;
}
ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
- } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0) {
+ } else if (!EVP_PKEY_verify_init(ctx->pctx)) {
return 0;
}
} else {
if (ctx->pctx->pmeth->signctx_init) {
- if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0) {
+ if (!ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx)) {
return 0;
}
ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
- } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0) {
+ } else if (!EVP_PKEY_sign_init(ctx->pctx)) {
return 0;
}
}
- if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0) {
+ if (!EVP_PKEY_CTX_set_signature_md(ctx->pctx, type)) {
return 0;
}
if (pctx) {
@@ -163,12 +162,12 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig,
r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx, out_sig, out_sig_len, &tmp_ctx);
} else {
r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
+ if (r) {
+ r = EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, md, mdlen);
+ }
}
EVP_MD_CTX_cleanup(&tmp_ctx);
- if (has_signctx || !r) {
- return r;
- }
- return EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, md, mdlen);
+ return r;
} else {
if (has_signctx) {
return ctx->pctx->pmeth->signctx(ctx->pctx, out_sig, out_sig_len, ctx);
@@ -185,21 +184,21 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig,
uint8_t md[EVP_MAX_MD_SIZE];
int r;
unsigned int mdlen;
- const int has_verifyctx = ctx->pctx->pmeth->verifyctx != NULL;
EVP_MD_CTX_init(&tmp_ctx);
if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) {
return 0;
}
- if (has_verifyctx) {
+ if (ctx->pctx->pmeth->verifyctx) {
r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx, sig, sig_len, &tmp_ctx);
} else {
r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
+ if (r) {
+ r = EVP_PKEY_verify(ctx->pctx, sig, sig_len, md, mdlen);
+ }
}
EVP_MD_CTX_cleanup(&tmp_ctx);
- if (has_verifyctx || !r) {
- return r;
- }
- return EVP_PKEY_verify(ctx->pctx, sig, sig_len, md, mdlen);
+
+ return r;
}
diff --git a/src/crypto/evp/evp.c b/src/crypto/evp/evp.c
index 8a1d513..58fd9a9 100644
--- a/src/crypto/evp/evp.c
+++ b/src/crypto/evp/evp.c
@@ -67,10 +67,12 @@
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/rsa.h>
+#include <openssl/thread.h>
#include "internal.h"
+extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth;
@@ -109,15 +111,14 @@ void EVP_PKEY_free(EVP_PKEY *pkey) {
}
free_it(pkey);
- if (pkey->attributes) {
- /* TODO(fork): layering: X509_ATTRIBUTE_free is an X.509 function. In
- * practice this path isn't called but should be removed in the future. */
- /*sk_X509_ATTRIBUTE_pop_free(pkey->attributes, X509_ATTRIBUTE_free);*/
- assert(0);
- }
OPENSSL_free(pkey);
}
+EVP_PKEY *EVP_PKEY_up_ref(EVP_PKEY *pkey) {
+ CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+ return pkey;
+}
+
int EVP_PKEY_is_opaque(const EVP_PKEY *pkey) {
if (pkey->ameth && pkey->ameth->pkey_opaque) {
return pkey->ameth->pkey_opaque(pkey);
@@ -142,8 +143,9 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
/* Compare parameters if the algorithm has them */
if (a->ameth->param_cmp) {
ret = a->ameth->param_cmp(a, b);
- if (ret <= 0)
+ if (ret <= 0) {
return ret;
+ }
}
if (a->ameth->pub_cmp) {
@@ -154,11 +156,6 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
return -2;
}
-EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey) {
- CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
- return pkey;
-}
-
int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) {
if (to->type != from->type) {
OPENSSL_PUT_ERROR(EVP, EVP_PKEY_copy_parameters, EVP_R_DIFFERENT_KEY_TYPES);
@@ -213,6 +210,8 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pengine, int nid) {
return &hmac_asn1_meth;
case EVP_PKEY_EC:
return &ec_asn1_meth;
+ case EVP_PKEY_DSA:
+ return &dsa_asn1_meth;
default:
return NULL;
}
@@ -236,18 +235,19 @@ EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const uint8_t *mac_key,
return NULL;
}
- if (EVP_PKEY_keygen_init(mac_ctx) <= 0 ||
- EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
- EVP_PKEY_CTRL_SET_MAC_KEY, mac_key_len,
- (uint8_t *)mac_key) <= 0 ||
- EVP_PKEY_keygen(mac_ctx, &ret) <= 0) {
+ if (!EVP_PKEY_keygen_init(mac_ctx) ||
+ !EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
+ EVP_PKEY_CTRL_SET_MAC_KEY, mac_key_len,
+ (uint8_t *)mac_key) ||
+ !EVP_PKEY_keygen(mac_ctx, &ret)) {
ret = NULL;
goto merr;
}
merr:
- if (mac_ctx)
+ if (mac_ctx) {
EVP_PKEY_CTX_free(mac_ctx);
+ }
return ret;
}
@@ -323,7 +323,7 @@ int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) {
}
int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key) {
- return EVP_PKEY_assign(pkey, EVP_PKEY_EC, key);
+ return EVP_PKEY_assign(pkey, EVP_PKEY_DH, key);
}
DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) {
@@ -435,6 +435,10 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
0, (void *)out_md);
}
+EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey) {
+ return EVP_PKEY_up_ref(pkey);
+}
+
void OpenSSL_add_all_algorithms(void) {}
void EVP_cleanup(void) {}
diff --git a/src/crypto/evp/evp_ctx.c b/src/crypto/evp/evp_ctx.c
index a383725..9f42274 100644
--- a/src/crypto/evp/evp_ctx.c
+++ b/src/crypto/evp/evp_ctx.c
@@ -120,14 +120,12 @@ static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) {
ret->operation = EVP_PKEY_OP_UNDEFINED;
if (pkey) {
- ret->pkey = EVP_PKEY_dup(pkey);
+ ret->pkey = EVP_PKEY_up_ref(pkey);
}
if (pmeth->init) {
if (pmeth->init(ret) <= 0) {
- if (pkey) {
- EVP_PKEY_free(ret->pkey);
- }
+ EVP_PKEY_free(ret->pkey);
OPENSSL_free(ret);
return NULL;
}
@@ -151,12 +149,8 @@ void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) {
if (ctx->pmeth && ctx->pmeth->cleanup) {
ctx->pmeth->cleanup(ctx);
}
- if (ctx->pkey) {
- EVP_PKEY_free(ctx->pkey);
- }
- if (ctx->peerkey) {
- EVP_PKEY_free(ctx->peerkey);
- }
+ EVP_PKEY_free(ctx->pkey);
+ EVP_PKEY_free(ctx->peerkey);
OPENSSL_free(ctx);
}
@@ -179,14 +173,14 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) {
rctx->operation = pctx->operation;
if (pctx->pkey) {
- rctx->pkey = EVP_PKEY_dup(pctx->pkey);
+ rctx->pkey = EVP_PKEY_up_ref(pctx->pkey);
if (rctx->pkey == NULL) {
goto err;
}
}
if (pctx->peerkey) {
- rctx->peerkey = EVP_PKEY_dup(pctx->peerkey);
+ rctx->peerkey = EVP_PKEY_up_ref(pctx->peerkey);
if (rctx->peerkey == NULL) {
goto err;
}
@@ -212,32 +206,25 @@ void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx) { return ctx->app_data; }
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd,
int p1, void *p2) {
- int ret;
if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_COMMAND_NOT_SUPPORTED);
- return -2;
+ return 0;
}
if (keytype != -1 && ctx->pmeth->pkey_id != keytype) {
- return -1;
+ return 0;
}
if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_NO_OPERATION_SET);
- return -1;
+ return 0;
}
if (optype != -1 && !(ctx->operation & optype)) {
OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_INVALID_OPERATION);
- return -1;
- }
-
- ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
-
- if (ret == -2) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_COMMAND_NOT_SUPPORTED);
+ return 0;
}
- return ret;
+ return ctx->pmeth->ctrl(ctx, cmd, p1, p2);
}
int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) {
@@ -434,9 +421,7 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) {
return 0;
}
- if (ctx->peerkey) {
- EVP_PKEY_free(ctx->peerkey);
- }
+ EVP_PKEY_free(ctx->peerkey);
ctx->peerkey = peer;
ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
@@ -446,7 +431,7 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) {
return 0;
}
- EVP_PKEY_dup(peer);
+ EVP_PKEY_up_ref(peer);
return 1;
}
diff --git a/src/crypto/evp/evp_error.c b/src/crypto/evp/evp_error.c
deleted file mode 100644
index b0d311e..0000000
--- a/src/crypto/evp/evp_error.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* Copyright (c) 2014, Google Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-
-#include <openssl/err.h>
-
-#include <openssl/evp.h>
-
-const ERR_STRING_DATA EVP_error_string_data[] = {
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DigestSignAlgorithm, 0), "EVP_DigestSignAlgorithm"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DigestVerifyInitFromAlgorithm, 0), "EVP_DigestVerifyInitFromAlgorithm"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_ctrl, 0), "EVP_PKEY_CTX_ctrl"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_dup, 0), "EVP_PKEY_CTX_dup"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_copy_parameters, 0), "EVP_PKEY_copy_parameters"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_decrypt, 0), "EVP_PKEY_decrypt"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_decrypt_init, 0), "EVP_PKEY_decrypt_init"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_derive, 0), "EVP_PKEY_derive"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_derive_init, 0), "EVP_PKEY_derive_init"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_derive_set_peer, 0), "EVP_PKEY_derive_set_peer"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_encrypt, 0), "EVP_PKEY_encrypt"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_encrypt_init, 0), "EVP_PKEY_encrypt_init"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_get1_DH, 0), "EVP_PKEY_get1_DH"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_get1_DSA, 0), "EVP_PKEY_get1_DSA"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_get1_EC_KEY, 0), "EVP_PKEY_get1_EC_KEY"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_get1_RSA, 0), "EVP_PKEY_get1_RSA"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_keygen, 0), "EVP_PKEY_keygen"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_keygen_init, 0), "EVP_PKEY_keygen_init"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_new, 0), "EVP_PKEY_new"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_set_type, 0), "EVP_PKEY_set_type"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_sign, 0), "EVP_PKEY_sign"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_sign_init, 0), "EVP_PKEY_sign_init"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_verify, 0), "EVP_PKEY_verify"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_verify_init, 0), "EVP_PKEY_verify_init"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_check_padding_md, 0), "check_padding_md"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_d2i_AutoPrivateKey, 0), "d2i_AutoPrivateKey"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_d2i_PrivateKey, 0), "d2i_PrivateKey"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_do_EC_KEY_print, 0), "do_EC_KEY_print"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_do_rsa_print, 0), "do_rsa_print"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_do_sigver_init, 0), "do_sigver_init"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_eckey_param2type, 0), "eckey_param2type"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_eckey_param_decode, 0), "eckey_param_decode"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_eckey_priv_decode, 0), "eckey_priv_decode"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_eckey_priv_encode, 0), "eckey_priv_encode"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_eckey_pub_decode, 0), "eckey_pub_decode"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_eckey_pub_encode, 0), "eckey_pub_encode"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_eckey_type2param, 0), "eckey_type2param"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_evp_pkey_ctx_new, 0), "evp_pkey_ctx_new"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_hmac_signctx, 0), "hmac_signctx"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_i2d_PublicKey, 0), "i2d_PublicKey"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_old_ec_priv_decode, 0), "old_ec_priv_decode"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_old_rsa_priv_decode, 0), "old_rsa_priv_decode"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_ec_ctrl, 0), "pkey_ec_ctrl"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_ec_derive, 0), "pkey_ec_derive"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_ec_keygen, 0), "pkey_ec_keygen"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_ec_paramgen, 0), "pkey_ec_paramgen"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_ec_sign, 0), "pkey_ec_sign"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_rsa_ctrl, 0), "pkey_rsa_ctrl"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_rsa_decrypt, 0), "pkey_rsa_decrypt"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_rsa_encrypt, 0), "pkey_rsa_encrypt"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_pkey_rsa_sign, 0), "pkey_rsa_sign"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_algor_to_md, 0), "rsa_algor_to_md"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_digest_verify_init_from_algorithm, 0), "rsa_digest_verify_init_from_algorithm"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_item_verify, 0), "rsa_item_verify"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_mgf1_to_md, 0), "rsa_mgf1_to_md"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_priv_decode, 0), "rsa_priv_decode"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_priv_encode, 0), "rsa_priv_encode"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_pss_to_ctx, 0), "rsa_pss_to_ctx"},
- {ERR_PACK(ERR_LIB_EVP, EVP_F_rsa_pub_decode, 0), "rsa_pub_decode"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BUFFER_TOO_SMALL), "BUFFER_TOO_SMALL"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_COMMAND_NOT_SUPPORTED), "COMMAND_NOT_SUPPORTED"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CONTEXT_NOT_INITIALISED), "CONTEXT_NOT_INITIALISED"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DECODE_ERROR), "DECODE_ERROR"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_KEY_TYPES), "DIFFERENT_KEY_TYPES"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_PARAMETERS), "DIFFERENT_PARAMETERS"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED), "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIGEST_DOES_NOT_MATCH), "DIGEST_DOES_NOT_MATCH"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_DSA_KEY), "EXPECTING_AN_DSA_KEY"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_EC_KEY_KEY), "EXPECTING_AN_EC_KEY_KEY"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_RSA_KEY), "EXPECTING_AN_RSA_KEY"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_DH_KEY), "EXPECTING_A_DH_KEY"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_DSA_KEY), "EXPECTING_A_DSA_KEY"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPLICIT_EC_PARAMETERS_NOT_SUPPORTED), "EXPLICIT_EC_PARAMETERS_NOT_SUPPORTED"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_CURVE), "INVALID_CURVE"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_DIGEST_LENGTH), "INVALID_DIGEST_LENGTH"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_DIGEST_TYPE), "INVALID_DIGEST_TYPE"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEYBITS), "INVALID_KEYBITS"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_MGF1_MD), "INVALID_MGF1_MD"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION), "INVALID_OPERATION"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_PADDING_MODE), "INVALID_PADDING_MODE"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_PSS_PARAMETERS), "INVALID_PSS_PARAMETERS"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_PSS_SALTLEN), "INVALID_PSS_SALTLEN"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SALT_LENGTH), "INVALID_SALT_LENGTH"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_TRAILER), "INVALID_TRAILER"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KDF_PARAMETER_ERROR), "KDF_PARAMETER_ERROR"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYS_NOT_SET), "KEYS_NOT_SET"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MISSING_PARAMETERS), "MISSING_PARAMETERS"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DEFAULT_DIGEST), "NO_DEFAULT_DIGEST"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEY_SET), "NO_KEY_SET"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_MDC2_SUPPORT), "NO_MDC2_SUPPORT"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_NID_FOR_CURVE), "NO_NID_FOR_CURVE"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_OPERATION_SET), "NO_OPERATION_SET"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_PARAMETERS_SET), "NO_PARAMETERS_SET"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), "OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATON_NOT_INITIALIZED), "OPERATON_NOT_INITIALIZED"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PEER_KEY_ERROR), "PEER_KEY_ERROR"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SHARED_INFO_ERROR), "SHARED_INFO_ERROR"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_DIGEST), "UNKNOWN_DIGEST"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_MASK_DIGEST), "UNKNOWN_MASK_DIGEST"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM), "UNKNOWN_MESSAGE_DIGEST_ALGORITHM"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE), "UNKNOWN_PUBLIC_KEY_TYPE"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_SIGNATURE_ALGORITHM), "UNKNOWN_SIGNATURE_ALGORITHM"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_ALGORITHM), "UNSUPPORTED_ALGORITHM"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_MASK_ALGORITHM), "UNSUPPORTED_MASK_ALGORITHM"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_MASK_PARAMETER), "UNSUPPORTED_MASK_PARAMETER"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE), "UNSUPPORTED_PUBLIC_KEY_TYPE"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_SIGNATURE_TYPE), "UNSUPPORTED_SIGNATURE_TYPE"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRONG_PUBLIC_KEY_TYPE), "WRONG_PUBLIC_KEY_TYPE"},
- {ERR_PACK(ERR_LIB_EVP, 0, EVP_R_X931_UNSUPPORTED), "X931_UNSUPPORTED"},
- {0, NULL},
-};
diff --git a/src/crypto/evp/evp_test.c b/src/crypto/evp/evp_extra_test.cc
index 3e74cd5..674547d 100644
--- a/src/crypto/evp/evp_test.c
+++ b/src/crypto/evp/evp_extra_test.cc
@@ -16,7 +16,8 @@
#include <stdio.h>
#include <stdlib.h>
-#include <openssl/bio.h>
+#include <vector>
+
#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include <openssl/digest.h>
@@ -25,9 +26,11 @@
#include <openssl/rsa.h>
#include <openssl/x509.h>
+#include "../test/scoped_types.h"
+
-/* kExampleRSAKeyDER is an RSA private key in ASN.1, DER format. Of course, you
- * should never use this key anywhere but in an example. */
+// kExampleRSAKeyDER is an RSA private key in ASN.1, DER format. Of course, you
+// should never use this key anywhere but in an example.
static const uint8_t kExampleRSAKeyDER[] = {
0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xf8,
0xb8, 0x6c, 0x83, 0xb4, 0xbc, 0xd9, 0xa8, 0x57, 0xc0, 0xa5, 0xb4, 0x59,
@@ -82,6 +85,81 @@ static const uint8_t kExampleRSAKeyDER[] = {
0x2d, 0x86, 0x9d, 0xa5, 0x20, 0x1b, 0xe5, 0xdf,
};
+static const uint8_t kExampleDSAKeyDER[] = {
+ 0x30, 0x82, 0x03, 0x56, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00,
+ 0x9e, 0x12, 0xfa, 0xb3, 0xde, 0x12, 0x21, 0x35, 0x01, 0xdd, 0x82, 0xaa,
+ 0x10, 0xca, 0x2d, 0x10, 0x1d, 0x2d, 0x4e, 0xbf, 0xef, 0x4d, 0x2a, 0x3f,
+ 0x8d, 0xaa, 0x0f, 0xe0, 0xce, 0xda, 0xd8, 0xd6, 0xaf, 0x85, 0x61, 0x6a,
+ 0xa2, 0xf3, 0x25, 0x2c, 0x0a, 0x2b, 0x5a, 0x6d, 0xb0, 0x9e, 0x6f, 0x14,
+ 0x90, 0x0e, 0x0d, 0xdb, 0x83, 0x11, 0x87, 0x6d, 0xd8, 0xf9, 0x66, 0x95,
+ 0x25, 0xf9, 0x9e, 0xd6, 0x59, 0x49, 0xe1, 0x84, 0xd5, 0x06, 0x47, 0x93,
+ 0x27, 0x11, 0x69, 0xa2, 0x28, 0x68, 0x0b, 0x95, 0xec, 0x12, 0xf5, 0x9a,
+ 0x8e, 0x20, 0xb2, 0x1f, 0x2b, 0x58, 0xeb, 0x2a, 0x20, 0x12, 0xd3, 0x5b,
+ 0xde, 0x2e, 0xe3, 0x51, 0x82, 0x2f, 0xe8, 0xf3, 0x2d, 0x0a, 0x33, 0x05,
+ 0x65, 0xdc, 0xce, 0x5c, 0x67, 0x2b, 0x72, 0x59, 0xc1, 0x4b, 0x24, 0x33,
+ 0xd0, 0xb5, 0xb2, 0xca, 0x2b, 0x2d, 0xb0, 0xab, 0x62, 0x6e, 0x8f, 0x13,
+ 0xf4, 0x7f, 0xe0, 0x34, 0x5d, 0x90, 0x4e, 0x72, 0x94, 0xbb, 0x03, 0x8e,
+ 0x9c, 0xe2, 0x1a, 0x9e, 0x58, 0x0b, 0x83, 0x35, 0x62, 0x78, 0x70, 0x6c,
+ 0xfe, 0x76, 0x84, 0x36, 0xc6, 0x9d, 0xe1, 0x49, 0xcc, 0xff, 0x98, 0xb4,
+ 0xaa, 0xb8, 0xcb, 0x4f, 0x63, 0x85, 0xc9, 0xf1, 0x02, 0xce, 0x59, 0x34,
+ 0x6e, 0xae, 0xef, 0x27, 0xe0, 0xad, 0x22, 0x2d, 0x53, 0xd6, 0xe8, 0x9c,
+ 0xc8, 0xcd, 0xe5, 0x77, 0x6d, 0xd0, 0x00, 0x57, 0xb0, 0x3f, 0x2d, 0x88,
+ 0xab, 0x3c, 0xed, 0xba, 0xfd, 0x7b, 0x58, 0x5f, 0x0b, 0x7f, 0x78, 0x35,
+ 0xe1, 0x7a, 0x37, 0x28, 0xbb, 0xf2, 0x5e, 0xa6, 0x25, 0x72, 0xf2, 0x45,
+ 0xdc, 0x11, 0x1f, 0x3c, 0xe3, 0x9c, 0xb6, 0xff, 0xac, 0xc3, 0x1b, 0x0a,
+ 0x27, 0x90, 0xe7, 0xbd, 0xe9, 0x02, 0x24, 0xea, 0x9b, 0x09, 0x31, 0x53,
+ 0x62, 0xaf, 0x3d, 0x2b, 0x02, 0x21, 0x00, 0xf3, 0x81, 0xdc, 0xf5, 0x3e,
+ 0xbf, 0x72, 0x4f, 0x8b, 0x2e, 0x5c, 0xa8, 0x2c, 0x01, 0x0f, 0xb4, 0xb5,
+ 0xed, 0xa9, 0x35, 0x8d, 0x0f, 0xd8, 0x8e, 0xd2, 0x78, 0x58, 0x94, 0x88,
+ 0xb5, 0x4f, 0xc3, 0x02, 0x82, 0x01, 0x00, 0x0c, 0x40, 0x2a, 0x72, 0x5d,
+ 0xcc, 0x3a, 0x62, 0xe0, 0x2b, 0xf4, 0xcf, 0x43, 0xcd, 0x17, 0xf4, 0xa4,
+ 0x93, 0x59, 0x12, 0x20, 0x22, 0x36, 0x69, 0xcf, 0x41, 0x93, 0xed, 0xab,
+ 0x42, 0x3a, 0xd0, 0x8d, 0xfb, 0x55, 0x2e, 0x30, 0x8a, 0x6a, 0x57, 0xa5,
+ 0xff, 0xbc, 0x7c, 0xd0, 0xfb, 0x20, 0x87, 0xf8, 0x1f, 0x8d, 0xf0, 0xcb,
+ 0x08, 0xab, 0x21, 0x33, 0x28, 0x7d, 0x2b, 0x69, 0x68, 0x71, 0x4a, 0x94,
+ 0xf6, 0x33, 0xc9, 0x40, 0x84, 0x5a, 0x48, 0xa3, 0xe1, 0x67, 0x08, 0xdd,
+ 0xe7, 0x61, 0xcc, 0x6a, 0x8e, 0xab, 0x2d, 0x84, 0xdb, 0x21, 0xb6, 0xea,
+ 0x5b, 0x07, 0x68, 0x14, 0x93, 0xcc, 0x9c, 0x31, 0xfb, 0xc3, 0x68, 0xb2,
+ 0x43, 0xf6, 0xdd, 0xf8, 0xc9, 0x32, 0xa8, 0xb4, 0x03, 0x8f, 0x44, 0xe7,
+ 0xb1, 0x5c, 0xa8, 0x76, 0x34, 0x4a, 0x14, 0x78, 0x59, 0xf2, 0xb4, 0x3b,
+ 0x39, 0x45, 0x86, 0x68, 0xad, 0x5e, 0x0a, 0x1a, 0x9a, 0x66, 0x95, 0x46,
+ 0xdd, 0x28, 0x12, 0xe3, 0xb3, 0x61, 0x7a, 0x0a, 0xef, 0x99, 0xd5, 0x8e,
+ 0x3b, 0xb4, 0xcc, 0x87, 0xfd, 0x94, 0x22, 0x5e, 0x01, 0xd2, 0xdc, 0xc4,
+ 0x69, 0xa7, 0x72, 0x68, 0x14, 0x6c, 0x51, 0x91, 0x8f, 0x18, 0xe8, 0xb4,
+ 0xd7, 0x0a, 0xa1, 0xf0, 0xc7, 0x62, 0x3b, 0xcc, 0x52, 0xcf, 0x37, 0x31,
+ 0xd3, 0x86, 0x41, 0xb2, 0xd2, 0x83, 0x0b, 0x7e, 0xec, 0xb2, 0xf0, 0x95,
+ 0x52, 0xff, 0x13, 0x7d, 0x04, 0x6e, 0x49, 0x4e, 0x7f, 0x33, 0xc3, 0x59,
+ 0x00, 0x02, 0xb1, 0x6d, 0x1b, 0x97, 0xd9, 0x36, 0xfd, 0xa2, 0x8f, 0x90,
+ 0xc3, 0xed, 0x3c, 0xa3, 0x53, 0x38, 0x16, 0x8a, 0xc1, 0x6f, 0x77, 0xc3,
+ 0xc5, 0x7a, 0xdc, 0x2e, 0x8f, 0x7c, 0x6c, 0x22, 0x56, 0xe4, 0x1a, 0x5f,
+ 0x65, 0x45, 0x05, 0x90, 0xdb, 0xb5, 0xbc, 0xf0, 0x6d, 0x66, 0x61, 0x02,
+ 0x82, 0x01, 0x00, 0x31, 0x97, 0x31, 0xa1, 0x4e, 0x38, 0x56, 0x88, 0xdb,
+ 0x94, 0x1d, 0xbf, 0x65, 0x5c, 0xda, 0x4b, 0xc2, 0x10, 0xde, 0x74, 0x20,
+ 0x03, 0xce, 0x13, 0x60, 0xf2, 0x25, 0x1d, 0x55, 0x7c, 0x5d, 0x94, 0x82,
+ 0x54, 0x08, 0x53, 0xdb, 0x85, 0x95, 0xbf, 0xdd, 0x5e, 0x50, 0xd5, 0x96,
+ 0xe0, 0x79, 0x51, 0x1b, 0xbf, 0x4d, 0x4e, 0xb9, 0x3a, 0xc5, 0xee, 0xc4,
+ 0x5e, 0x98, 0x75, 0x7b, 0xbe, 0xff, 0x30, 0xe6, 0xd0, 0x7b, 0xa6, 0xf1,
+ 0xbc, 0x29, 0xea, 0xdf, 0xec, 0xf3, 0x8b, 0xfa, 0x83, 0x11, 0x9f, 0x3f,
+ 0xf0, 0x5d, 0x06, 0x51, 0x32, 0xaa, 0x21, 0xfc, 0x26, 0x17, 0xe7, 0x50,
+ 0xc2, 0x16, 0xba, 0xfa, 0x54, 0xb7, 0x7e, 0x1d, 0x2c, 0xa6, 0xa3, 0x41,
+ 0x66, 0x33, 0x94, 0x83, 0xb9, 0xbf, 0xa0, 0x4f, 0xbd, 0xa6, 0xfd, 0x2c,
+ 0x81, 0x58, 0x35, 0x33, 0x39, 0xc0, 0x6d, 0x33, 0x40, 0x56, 0x64, 0x12,
+ 0x5a, 0xcd, 0x35, 0x53, 0x21, 0x78, 0x8f, 0x27, 0x24, 0x37, 0x66, 0x8a,
+ 0xdf, 0x5e, 0x5f, 0x63, 0xfc, 0x8b, 0x2d, 0xef, 0x57, 0xdb, 0x40, 0x25,
+ 0xd5, 0x17, 0x53, 0x0b, 0xe4, 0xa5, 0xae, 0x54, 0xbf, 0x46, 0x4f, 0xa6,
+ 0x79, 0xc3, 0x74, 0xfa, 0x1f, 0x85, 0x34, 0x64, 0x6d, 0xc5, 0x03, 0xeb,
+ 0x72, 0x98, 0x80, 0x7b, 0xc0, 0x8f, 0x35, 0x11, 0xa7, 0x09, 0xeb, 0x51,
+ 0xe0, 0xb0, 0xac, 0x92, 0x14, 0xf2, 0xad, 0x37, 0x95, 0x5a, 0xba, 0x8c,
+ 0xc4, 0xdb, 0xed, 0xc4, 0x4e, 0x8b, 0x8f, 0x84, 0x33, 0x64, 0xf8, 0x57,
+ 0x12, 0xd7, 0x08, 0x7e, 0x90, 0x66, 0xdf, 0x91, 0x50, 0x23, 0xf2, 0x73,
+ 0xc0, 0x6b, 0xb1, 0x15, 0xdd, 0x64, 0xd7, 0xc9, 0x75, 0x17, 0x73, 0x72,
+ 0xda, 0x33, 0xc4, 0x6f, 0xa5, 0x47, 0xa1, 0xcc, 0xd1, 0xc6, 0x62, 0xe5,
+ 0xca, 0xab, 0x5f, 0x2a, 0x8f, 0x6b, 0xcc, 0x02, 0x21, 0x00, 0xb0, 0xc7,
+ 0x68, 0x70, 0x27, 0x43, 0xbc, 0x51, 0x24, 0x29, 0x93, 0xa9, 0x71, 0xa5,
+ 0x28, 0x89, 0x79, 0x54, 0x44, 0xf7, 0xc6, 0x45, 0x22, 0x03, 0xd0, 0xce,
+ 0x84, 0xfe, 0x61, 0x17, 0xd4, 0x6e,
+};
+
static const uint8_t kMsg[] = {1, 2, 3, 4};
static const uint8_t kSignature[] = {
@@ -98,8 +176,8 @@ static const uint8_t kSignature[] = {
0x55, 0xa7, 0xab, 0x45, 0x02, 0x97, 0x60, 0x42,
};
-/* kExamplePSSCert is an example self-signed certificate, signed with
- * kExampleRSAKeyDER using RSA-PSS with default hash functions. */
+// kExamplePSSCert is an example self-signed certificate, signed with
+// kExampleRSAKeyDER using RSA-PSS with default hash functions.
static const uint8_t kExamplePSSCert[] = {
0x30, 0x82, 0x02, 0x62, 0x30, 0x82, 0x01, 0xc6, 0xa0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x09, 0x00, 0x8d, 0xea, 0x53, 0x24, 0xfa, 0x48, 0x87, 0xf3,
@@ -155,8 +233,8 @@ static const uint8_t kExamplePSSCert[] = {
0x8c, 0x16,
};
-/* kExampleRSAKeyPKCS8 is kExampleRSAKeyDER encoded in a PKCS #8
- * PrivateKeyInfo. */
+// kExampleRSAKeyPKCS8 is kExampleRSAKeyDER encoded in a PKCS #8
+// PrivateKeyInfo.
static const uint8_t kExampleRSAKeyPKCS8[] = {
0x30, 0x82, 0x02, 0x76, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
@@ -213,8 +291,8 @@ static const uint8_t kExampleRSAKeyPKCS8[] = {
0x08, 0xf1, 0x2d, 0x86, 0x9d, 0xa5, 0x20, 0x1b, 0xe5, 0xdf,
};
-/* kExampleECKeyDER is a sample EC private key encoded as an ECPrivateKey
- * structure. */
+// kExampleECKeyDER is a sample EC private key encoded as an ECPrivateKey
+// structure.
static const uint8_t kExampleECKeyDER[] = {
0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x07, 0x0f, 0x08, 0x72, 0x7a,
0xd4, 0xa0, 0x4a, 0x9c, 0xdd, 0x59, 0xc9, 0x4d, 0x89, 0x68, 0x77, 0x08,
@@ -229,8 +307,8 @@ static const uint8_t kExampleECKeyDER[] = {
0xc1,
};
-/* kExampleBadECKeyDER is a sample EC private key encoded as an ECPrivateKey
- * structure. The private key is equal to the order and will fail to import */
+// kExampleBadECKeyDER is a sample EC private key encoded as an ECPrivateKey
+// structure. The private key is equal to the order and will fail to import.
static const uint8_t kExampleBadECKeyDER[] = {
0x30, 0x66, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48,
0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03,
@@ -243,237 +321,143 @@ static const uint8_t kExampleBadECKeyDER[] = {
0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
};
-static EVP_PKEY *load_example_rsa_key(void) {
- EVP_PKEY *ret = NULL;
+static ScopedEVP_PKEY LoadExampleRSAKey() {
const uint8_t *derp = kExampleRSAKeyDER;
- EVP_PKEY *pkey = NULL;
- RSA *rsa = NULL;
-
- if (!d2i_RSAPrivateKey(&rsa, &derp, sizeof(kExampleRSAKeyDER))) {
- return NULL;
- }
-
- pkey = EVP_PKEY_new();
- if (pkey == NULL || !EVP_PKEY_set1_RSA(pkey, rsa)) {
- goto out;
- }
-
- ret = pkey;
- pkey = NULL;
-
-out:
- if (pkey) {
- EVP_PKEY_free(pkey);
+ ScopedRSA rsa(d2i_RSAPrivateKey(nullptr, &derp, sizeof(kExampleRSAKeyDER)));
+ if (!rsa) {
+ return nullptr;
}
- if (rsa) {
- RSA_free(rsa);
+ ScopedEVP_PKEY pkey(EVP_PKEY_new());
+ if (!pkey || !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) {
+ return nullptr;
}
-
- return ret;
+ return pkey;
}
-static int test_EVP_DigestSignInit(void) {
- int ret = 0;
- EVP_PKEY *pkey = NULL;
- uint8_t *sig = NULL;
- size_t sig_len = 0;
- EVP_MD_CTX md_ctx, md_ctx_verify;
-
- EVP_MD_CTX_init(&md_ctx);
- EVP_MD_CTX_init(&md_ctx_verify);
-
- pkey = load_example_rsa_key();
- if (pkey == NULL ||
- !EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL, pkey) ||
- !EVP_DigestSignUpdate(&md_ctx, kMsg, sizeof(kMsg))) {
- goto out;
+static bool TestEVP_DigestSignInit(void) {
+ ScopedEVP_PKEY pkey = LoadExampleRSAKey();
+ ScopedEVP_MD_CTX md_ctx;
+ if (!pkey ||
+ !EVP_DigestSignInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) ||
+ !EVP_DigestSignUpdate(md_ctx.get(), kMsg, sizeof(kMsg))) {
+ return false;
}
- /* Determine the size of the signature. */
- if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len)) {
- goto out;
+ // Determine the size of the signature.
+ size_t sig_len = 0;
+ if (!EVP_DigestSignFinal(md_ctx.get(), NULL, &sig_len)) {
+ return false;
}
- /* Sanity check for testing. */
- if (sig_len != EVP_PKEY_size(pkey)) {
+ // Sanity check for testing.
+ if (sig_len != (size_t)EVP_PKEY_size(pkey.get())) {
fprintf(stderr, "sig_len mismatch\n");
- goto out;
+ return false;
}
- sig = malloc(sig_len);
- if (sig == NULL || !EVP_DigestSignFinal(&md_ctx, sig, &sig_len)) {
- goto out;
+ std::vector<uint8_t> sig;
+ sig.resize(sig_len);
+ if (!EVP_DigestSignFinal(md_ctx.get(), bssl::vector_data(&sig), &sig_len)) {
+ return false;
}
+ sig.resize(sig_len);
- /* Ensure that the signature round-trips. */
- if (!EVP_DigestVerifyInit(&md_ctx_verify, NULL, EVP_sha256(), NULL, pkey) ||
- !EVP_DigestVerifyUpdate(&md_ctx_verify, kMsg, sizeof(kMsg)) ||
- !EVP_DigestVerifyFinal(&md_ctx_verify, sig, sig_len)) {
- goto out;
+ // Ensure that the signature round-trips.
+ md_ctx.Reset();
+ if (!EVP_DigestVerifyInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) ||
+ !EVP_DigestVerifyUpdate(md_ctx.get(), kMsg, sizeof(kMsg)) ||
+ !EVP_DigestVerifyFinal(md_ctx.get(), bssl::vector_data(&sig), sig_len)) {
+ return false;
}
- ret = 1;
-
-out:
- if (!ret) {
- BIO_print_errors_fp(stderr);
- }
-
- EVP_MD_CTX_cleanup(&md_ctx);
- EVP_MD_CTX_cleanup(&md_ctx_verify);
- if (pkey) {
- EVP_PKEY_free(pkey);
- }
- if (sig) {
- free(sig);
- }
-
- return ret;
+ return true;
}
-static int test_EVP_DigestVerifyInit(void) {
- int ret = 0;
- EVP_PKEY *pkey = NULL;
- EVP_MD_CTX md_ctx;
-
- EVP_MD_CTX_init(&md_ctx);
-
- pkey = load_example_rsa_key();
- if (pkey == NULL ||
- !EVP_DigestVerifyInit(&md_ctx, NULL, EVP_sha256(), NULL, pkey) ||
- !EVP_DigestVerifyUpdate(&md_ctx, kMsg, sizeof(kMsg)) ||
- !EVP_DigestVerifyFinal(&md_ctx, kSignature, sizeof(kSignature))) {
- goto out;
- }
- ret = 1;
-
-out:
- if (!ret) {
- BIO_print_errors_fp(stderr);
- }
-
- EVP_MD_CTX_cleanup(&md_ctx);
- if (pkey) {
- EVP_PKEY_free(pkey);
- }
-
- return ret;
+static bool TestEVP_DigestVerifyInit(void) {
+ ScopedEVP_PKEY pkey = LoadExampleRSAKey();
+ ScopedEVP_MD_CTX md_ctx;
+ if (!pkey ||
+ !EVP_DigestVerifyInit(md_ctx.get(), NULL, EVP_sha256(), NULL,
+ pkey.get()) ||
+ !EVP_DigestVerifyUpdate(md_ctx.get(), kMsg, sizeof(kMsg)) ||
+ !EVP_DigestVerifyFinal(md_ctx.get(), kSignature, sizeof(kSignature))) {
+ return false;
+ }
+ return true;
}
-/* test_algorithm_roundtrip signs a message using an already-initialized
- * |md_ctx|, sampling the AlgorithmIdentifier. It then uses |pkey| and the
- * AlgorithmIdentifier to verify the signature. */
-static int test_algorithm_roundtrip(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) {
- int ret = 0;
- uint8_t *sig = NULL;
- size_t sig_len = 0;
- EVP_MD_CTX md_ctx_verify;
- X509_ALGOR *algor = NULL;
-
- EVP_MD_CTX_init(&md_ctx_verify);
-
+// TestAlgorithmRoundtrip signs a message using an already-initialized
+// |md_ctx|, sampling the AlgorithmIdentifier. It then uses |pkey| and the
+// AlgorithmIdentifier to verify the signature.
+static bool TestAlgorithmRoundtrip(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) {
if (!EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg))) {
- goto out;
+ return false;
}
- /* Save the algorithm. */
- algor = X509_ALGOR_new();
- if (algor == NULL || !EVP_DigestSignAlgorithm(md_ctx, algor)) {
- goto out;
+ // Save the algorithm.
+ ScopedX509_ALGOR algor(X509_ALGOR_new());
+ if (!algor || !EVP_DigestSignAlgorithm(md_ctx, algor.get())) {
+ return false;
}
- /* Determine the size of the signature. */
+ // Determine the size of the signature.
+ size_t sig_len = 0;
if (!EVP_DigestSignFinal(md_ctx, NULL, &sig_len)) {
- goto out;
+ return false;
}
- /* Sanity check for testing. */
- if (sig_len != EVP_PKEY_size(pkey)) {
+ // Sanity check for testing.
+ if (sig_len != (size_t)EVP_PKEY_size(pkey)) {
fprintf(stderr, "sig_len mismatch\n");
- goto out;
+ return false;
}
- sig = malloc(sig_len);
- if (sig == NULL || !EVP_DigestSignFinal(md_ctx, sig, &sig_len)) {
- goto out;
+ std::vector<uint8_t> sig;
+ sig.resize(sig_len);
+ if (!EVP_DigestSignFinal(md_ctx, bssl::vector_data(&sig), &sig_len)) {
+ return false;
}
+ sig.resize(sig_len);
- /* Ensure that the signature round-trips. */
- if (!EVP_DigestVerifyInitFromAlgorithm(&md_ctx_verify, algor, pkey) ||
- !EVP_DigestVerifyUpdate(&md_ctx_verify, kMsg, sizeof(kMsg)) ||
- !EVP_DigestVerifyFinal(&md_ctx_verify, sig, sig_len)) {
- goto out;
+ // Ensure that the signature round-trips.
+ ScopedEVP_MD_CTX md_ctx_verify;
+ if (!EVP_DigestVerifyInitFromAlgorithm(md_ctx_verify.get(), algor.get(),
+ pkey) ||
+ !EVP_DigestVerifyUpdate(md_ctx_verify.get(), kMsg, sizeof(kMsg)) ||
+ !EVP_DigestVerifyFinal(md_ctx_verify.get(), bssl::vector_data(&sig),
+ sig_len)) {
+ return false;
}
- ret = 1;
-
-out:
- EVP_MD_CTX_cleanup(&md_ctx_verify);
- if (sig) {
- free(sig);
- }
- if (algor) {
- X509_ALGOR_free(algor);
- }
-
- return ret;
+ return true;
}
-static int test_EVP_DigestSignAlgorithm(void) {
- int ret = 0;
- EVP_PKEY *pkey = NULL;
- EVP_MD_CTX md_ctx;
- EVP_PKEY_CTX *pkey_ctx;
-
- EVP_MD_CTX_init(&md_ctx);
-
- pkey = load_example_rsa_key();
- if (pkey == NULL) {
- goto out;
- }
+static bool TestEVP_DigestSignAlgorithm(void) {
+ ScopedEVP_PKEY pkey = LoadExampleRSAKey();
- /* Test a simple AlgorithmIdentifier. */
- if (!EVP_DigestSignInit(&md_ctx, &pkey_ctx, EVP_sha256(), NULL, pkey) ||
- !test_algorithm_roundtrip(&md_ctx, pkey)) {
+ // Test a simple AlgorithmIdentifier.
+ ScopedEVP_MD_CTX md_ctx;
+ if (!pkey ||
+ !EVP_DigestSignInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) ||
+ !TestAlgorithmRoundtrip(md_ctx.get(), pkey.get())) {
fprintf(stderr, "RSA with SHA-256 failed\n");
- goto out;
+ return false;
}
- EVP_MD_CTX_cleanup(&md_ctx);
- EVP_MD_CTX_init(&md_ctx);
-
- /* Test RSA-PSS with custom parameters. */
- if (!EVP_DigestSignInit(&md_ctx, &pkey_ctx, EVP_sha256(), NULL, pkey) ||
- EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1 ||
- EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha512()) != 1 ||
- !test_algorithm_roundtrip(&md_ctx, pkey)) {
+ // Test RSA-PSS with custom parameters.
+ md_ctx.Reset();
+ EVP_PKEY_CTX *pkey_ctx;
+ if (!EVP_DigestSignInit(md_ctx.get(), &pkey_ctx, EVP_sha256(), NULL,
+ pkey.get()) ||
+ !EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) ||
+ !EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, EVP_sha512()) ||
+ !TestAlgorithmRoundtrip(md_ctx.get(), pkey.get())) {
fprintf(stderr, "RSA-PSS failed\n");
- goto out;
- }
-
- ret = 1;
-
-out:
- if (!ret) {
- BIO_print_errors_fp(stderr);
+ return false;
}
- EVP_MD_CTX_cleanup(&md_ctx);
- if (pkey) {
- EVP_PKEY_free(pkey);
- }
-
- return ret;
+ return true;
}
-static int test_EVP_DigestVerifyInitFromAlgorithm(void) {
- int ret = 0;
+static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
CBS cert, cert_body, tbs_cert, algorithm, signature;
- uint8_t padding;
- X509_ALGOR *algor = NULL;
- const uint8_t *derp;
- EVP_PKEY *pkey = NULL;
- EVP_MD_CTX md_ctx;
-
- EVP_MD_CTX_init(&md_ctx);
-
CBS_init(&cert, kExamplePSSCert, sizeof(kExamplePSSCert));
if (!CBS_get_asn1(&cert, &cert_body, CBS_ASN1_SEQUENCE) ||
CBS_len(&cert) != 0 ||
@@ -482,155 +466,133 @@ static int test_EVP_DigestVerifyInitFromAlgorithm(void) {
!CBS_get_asn1(&cert_body, &signature, CBS_ASN1_BITSTRING) ||
CBS_len(&cert_body) != 0) {
fprintf(stderr, "Failed to parse certificate\n");
- goto out;
+ return false;
}
- /* Signatures are BIT STRINGs, but they have are multiple of 8 bytes, so the
- leading phase byte is just a zero. */
+ // Signatures are BIT STRINGs, but they have are multiple of 8 bytes, so the
+ // leading phase byte is just a zero.
+ uint8_t padding;
if (!CBS_get_u8(&signature, &padding) || padding != 0) {
fprintf(stderr, "Invalid signature padding\n");
- goto out;
+ return false;
}
- derp = CBS_data(&algorithm);
- if (!d2i_X509_ALGOR(&algor, &derp, CBS_len(&algorithm)) ||
- derp != CBS_data(&algorithm) + CBS_len(&algorithm)) {
+ const uint8_t *derp = CBS_data(&algorithm);
+ ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &derp, CBS_len(&algorithm)));
+ if (!algor || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) {
fprintf(stderr, "Failed to parse algorithm\n");
+ return false;
}
- pkey = load_example_rsa_key();
- if (pkey == NULL ||
- !EVP_DigestVerifyInitFromAlgorithm(&md_ctx, algor, pkey) ||
- !EVP_DigestVerifyUpdate(&md_ctx, CBS_data(&tbs_cert),
+ ScopedEVP_PKEY pkey = LoadExampleRSAKey();
+ ScopedEVP_MD_CTX md_ctx;
+ if (!pkey ||
+ !EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
+ pkey.get()) ||
+ !EVP_DigestVerifyUpdate(md_ctx.get(), CBS_data(&tbs_cert),
CBS_len(&tbs_cert)) ||
- !EVP_DigestVerifyFinal(&md_ctx, CBS_data(&signature),
+ !EVP_DigestVerifyFinal(md_ctx.get(), CBS_data(&signature),
CBS_len(&signature))) {
- goto out;
- }
- ret = 1;
-
-out:
- if (!ret) {
- BIO_print_errors_fp(stderr);
+ return false;
}
-
- EVP_MD_CTX_cleanup(&md_ctx);
- if (pkey) {
- EVP_PKEY_free(pkey);
- }
-
- return ret;
+ return true;
}
-static int test_d2i_AutoPrivateKey(const uint8_t *input, size_t input_len,
+static bool Testd2i_AutoPrivateKey(const uint8_t *input, size_t input_len,
int expected_id) {
- int ret = 0;
- const uint8_t *p;
- EVP_PKEY *pkey = NULL;
-
- p = input;
- pkey = d2i_AutoPrivateKey(NULL, &p, input_len);
- if (pkey == NULL || p != input + input_len) {
+ const uint8_t *p = input;
+ ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, input_len));
+ if (!pkey || p != input + input_len) {
fprintf(stderr, "d2i_AutoPrivateKey failed\n");
- goto done;
+ return false;
}
- if (EVP_PKEY_id(pkey) != expected_id) {
+ if (EVP_PKEY_id(pkey.get()) != expected_id) {
fprintf(stderr, "Did not decode expected type\n");
- goto done;
+ return false;
}
- ret = 1;
-
-done:
- if (!ret) {
- BIO_print_errors_fp(stderr);
- }
-
- if (pkey != NULL) {
- EVP_PKEY_free(pkey);
- }
- return ret;
+ return true;
}
-/* Tests loading a bad key in PKCS8 format */
-static int test_EVP_PKCS82PKEY(void) {
- int ret = 0;
+// TestEVP_PKCS82PKEY tests loading a bad key in PKCS8 format.
+static bool TestEVP_PKCS82PKEY(void) {
const uint8_t *derp = kExampleBadECKeyDER;
- PKCS8_PRIV_KEY_INFO *p8inf = NULL;
- EVP_PKEY *pkey = NULL;
-
- p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, sizeof(kExampleBadECKeyDER));
-
+ ScopedPKCS8_PRIV_KEY_INFO p8inf(
+ d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, sizeof(kExampleBadECKeyDER)));
if (!p8inf || derp != kExampleBadECKeyDER + sizeof(kExampleBadECKeyDER)) {
fprintf(stderr, "Failed to parse key\n");
- goto done;
+ return false;
}
- pkey = EVP_PKCS82PKEY(p8inf);
+ ScopedEVP_PKEY pkey(EVP_PKCS82PKEY(p8inf.get()));
if (pkey) {
fprintf(stderr, "Imported invalid EC key\n");
- goto done;
+ return false;
}
- ret = 1;
-
-done:
- if (p8inf != NULL) {
- PKCS8_PRIV_KEY_INFO_free(p8inf);
- }
-
- if (pkey != NULL) {
- EVP_PKEY_free(pkey);
- }
-
- return ret;
+ return true;
}
int main(void) {
CRYPTO_library_init();
ERR_load_crypto_strings();
- if (!test_EVP_DigestSignInit()) {
+ if (!TestEVP_DigestSignInit()) {
fprintf(stderr, "EVP_DigestSignInit failed\n");
+ ERR_print_errors_fp(stderr);
return 1;
}
- if (!test_EVP_DigestVerifyInit()) {
+ if (!TestEVP_DigestVerifyInit()) {
fprintf(stderr, "EVP_DigestVerifyInit failed\n");
+ ERR_print_errors_fp(stderr);
return 1;
}
- if (!test_EVP_DigestSignAlgorithm()) {
+ if (!TestEVP_DigestSignAlgorithm()) {
fprintf(stderr, "EVP_DigestSignInit failed\n");
+ ERR_print_errors_fp(stderr);
return 1;
}
- if (!test_EVP_DigestVerifyInitFromAlgorithm()) {
+ if (!TestEVP_DigestVerifyInitFromAlgorithm()) {
fprintf(stderr, "EVP_DigestVerifyInitFromAlgorithm failed\n");
+ ERR_print_errors_fp(stderr);
return 1;
}
- if (!test_d2i_AutoPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER),
- EVP_PKEY_RSA)) {
+ if (!Testd2i_AutoPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER),
+ EVP_PKEY_RSA)) {
fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n");
+ ERR_print_errors_fp(stderr);
return 1;
}
- if (!test_d2i_AutoPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8),
- EVP_PKEY_RSA)) {
+ if (!Testd2i_AutoPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8),
+ EVP_PKEY_RSA)) {
fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n");
+ ERR_print_errors_fp(stderr);
return 1;
}
- if (!test_d2i_AutoPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER),
- EVP_PKEY_EC)) {
+ if (!Testd2i_AutoPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER),
+ EVP_PKEY_EC)) {
fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n");
+ ERR_print_errors_fp(stderr);
+ return 1;
+ }
+
+ if (!Testd2i_AutoPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER),
+ EVP_PKEY_DSA)) {
+ fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n");
+ ERR_print_errors_fp(stderr);
return 1;
}
- if (!test_EVP_PKCS82PKEY()) {
- fprintf(stderr, "test_EVP_PKCS82PKEY failed\n");
+ if (!TestEVP_PKCS82PKEY()) {
+ fprintf(stderr, "TestEVP_PKCS82PKEY failed\n");
+ ERR_print_errors_fp(stderr);
return 1;
}
diff --git a/src/crypto/evp/evp_test.cc b/src/crypto/evp/evp_test.cc
new file mode 100644
index 0000000..239f868
--- /dev/null
+++ b/src/crypto/evp/evp_test.cc
@@ -0,0 +1,262 @@
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2015 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <openssl/bio.h>
+#include <openssl/crypto.h>
+#include <openssl/digest.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+
+#include "../test/file_test.h"
+#include "../test/scoped_types.h"
+#include "../test/stl_compat.h"
+
+
+// evp_test dispatches between multiple test types. HMAC tests test the legacy
+// EVP_PKEY_HMAC API. PrivateKey tests take a key name parameter and single
+// block, decode it as a PEM private key, and save it under that key name.
+// Decrypt, Sign, and Verify tests take a previously imported key name as
+// parameter and test their respective operations.
+
+static const EVP_MD *GetDigest(FileTest *t, const std::string &name) {
+ if (name == "MD5") {
+ return EVP_md5();
+ } else if (name == "SHA1") {
+ return EVP_sha1();
+ } else if (name == "SHA224") {
+ return EVP_sha224();
+ } else if (name == "SHA256") {
+ return EVP_sha256();
+ } else if (name == "SHA384") {
+ return EVP_sha384();
+ } else if (name == "SHA512") {
+ return EVP_sha512();
+ }
+ t->PrintLine("Unknown digest: '%s'", name.c_str());
+ return nullptr;
+}
+
+using KeyMap = std::map<std::string, EVP_PKEY*>;
+
+// ImportPrivateKey evaluates a PrivateKey test in |t| and writes the resulting
+// private key to |key_map|.
+static bool ImportPrivateKey(FileTest *t, KeyMap *key_map) {
+ const std::string &key_name = t->GetParameter();
+ if (key_map->count(key_name) > 0) {
+ t->PrintLine("Duplicate key '%s'.", key_name.c_str());
+ return false;
+ }
+ const std::string &block = t->GetBlock();
+ ScopedBIO bio(BIO_new_mem_buf(const_cast<char*>(block.data()), block.size()));
+ if (!bio) {
+ return false;
+ }
+ ScopedEVP_PKEY pkey(PEM_read_bio_PrivateKey(bio.get(), nullptr, 0, nullptr));
+ if (!pkey) {
+ t->PrintLine("Error reading private key.");
+ return false;
+ }
+ (*key_map)[key_name] = pkey.release();
+ return true;
+}
+
+static bool TestHMAC(FileTest *t) {
+ std::string digest_str;
+ if (!t->GetAttribute(&digest_str, "HMAC")) {
+ return false;
+ }
+ const EVP_MD *digest = GetDigest(t, digest_str);
+ if (digest == nullptr) {
+ return false;
+ }
+
+ std::vector<uint8_t> key, input, output;
+ if (!t->GetBytes(&key, "Key") ||
+ !t->GetBytes(&input, "Input") ||
+ !t->GetBytes(&output, "Output")) {
+ return false;
+ }
+
+ ScopedEVP_PKEY pkey(EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr,
+ bssl::vector_data(&key),
+ key.size()));
+ ScopedEVP_MD_CTX mctx;
+ if (!pkey ||
+ !EVP_DigestSignInit(mctx.get(), nullptr, digest, nullptr, pkey.get()) ||
+ !EVP_DigestSignUpdate(mctx.get(), bssl::vector_data(&input),
+ input.size())) {
+ return false;
+ }
+
+ size_t len;
+ std::vector<uint8_t> actual;
+ if (!EVP_DigestSignFinal(mctx.get(), nullptr, &len)) {
+ return false;
+ }
+ actual.resize(len);
+ if (!EVP_DigestSignFinal(mctx.get(), bssl::vector_data(&actual), &len)) {
+ return false;
+ }
+ actual.resize(len);
+ return t->ExpectBytesEqual(bssl::vector_data(&output), output.size(),
+ bssl::vector_data(&actual), actual.size());
+}
+
+static bool TestEVP(FileTest *t, void *arg) {
+ KeyMap *key_map = reinterpret_cast<KeyMap*>(arg);
+ if (t->GetType() == "PrivateKey") {
+ return ImportPrivateKey(t, key_map);
+ } else if (t->GetType() == "HMAC") {
+ return TestHMAC(t);
+ }
+
+ int (*key_op_init)(EVP_PKEY_CTX *ctx);
+ int (*key_op)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len,
+ const uint8_t *in, size_t in_len);
+ if (t->GetType() == "Decrypt") {
+ key_op_init = EVP_PKEY_decrypt_init;
+ key_op = EVP_PKEY_decrypt;
+ } else if (t->GetType() == "Sign") {
+ key_op_init = EVP_PKEY_sign_init;
+ key_op = EVP_PKEY_sign;
+ } else if (t->GetType() == "Verify") {
+ key_op_init = EVP_PKEY_verify_init;
+ key_op = nullptr; // EVP_PKEY_verify is handled differently.
+ } else {
+ t->PrintLine("Unknown test '%s'", t->GetType().c_str());
+ return false;
+ }
+
+ // Load the key.
+ const std::string &key_name = t->GetParameter();
+ if (key_map->count(key_name) == 0) {
+ t->PrintLine("Could not find key '%s'.", key_name.c_str());
+ return false;
+ }
+ EVP_PKEY *key = (*key_map)[key_name];
+
+ std::vector<uint8_t> input, output;
+ if (!t->GetBytes(&input, "Input") ||
+ !t->GetBytes(&output, "Output")) {
+ return false;
+ }
+
+ // Set up the EVP_PKEY_CTX.
+ ScopedEVP_PKEY_CTX ctx(EVP_PKEY_CTX_new(key, nullptr));
+ if (!ctx || !key_op_init(ctx.get())) {
+ return false;
+ }
+ if (t->HasAttribute("Digest")) {
+ const EVP_MD *digest = GetDigest(t, t->GetAttributeOrDie("Digest"));
+ if (digest == nullptr ||
+ !EVP_PKEY_CTX_set_signature_md(ctx.get(), digest)) {
+ return false;
+ }
+ }
+
+ if (t->GetType() == "Verify") {
+ if (!EVP_PKEY_verify(ctx.get(), bssl::vector_data(&output), output.size(),
+ bssl::vector_data(&input), input.size())) {
+ // ECDSA sometimes doesn't push an error code. Push one on the error queue
+ // so it's distinguishable from other errors.
+ ERR_put_error(ERR_LIB_USER, 0, ERR_R_EVP_LIB, __FILE__, __LINE__);
+ return false;
+ }
+ return true;
+ }
+
+ size_t len;
+ std::vector<uint8_t> actual;
+ if (!key_op(ctx.get(), nullptr, &len, bssl::vector_data(&input),
+ input.size())) {
+ return false;
+ }
+ actual.resize(len);
+ if (!key_op(ctx.get(), bssl::vector_data(&actual), &len,
+ bssl::vector_data(&input), input.size())) {
+ return false;
+ }
+ actual.resize(len);
+ if (!t->ExpectBytesEqual(bssl::vector_data(&output), output.size(),
+ bssl::vector_data(&actual), len)) {
+ return false;
+ }
+ return true;
+}
+
+int main(int argc, char **argv) {
+ CRYPTO_library_init();
+ if (argc != 2) {
+ fprintf(stderr, "%s <test file.txt>\n", argv[0]);
+ return 1;
+ }
+
+ KeyMap map;
+ int ret = FileTestMain(TestEVP, &map, argv[1]);
+ // TODO(davidben): When we can rely on a move-aware std::map, make KeyMap a
+ // map of ScopedEVP_PKEY instead.
+ for (const auto &pair : map) {
+ EVP_PKEY_free(pair.second);
+ }
+ return ret;
+}
diff --git a/src/crypto/evp/evp_tests.txt b/src/crypto/evp/evp_tests.txt
new file mode 100644
index 0000000..cccfa4f
--- /dev/null
+++ b/src/crypto/evp/evp_tests.txt
@@ -0,0 +1,174 @@
+# Public key algorithm tests
+
+# Private keys used for PKEY operations.
+
+# RSA 2048 bit key.
+
+PrivateKey = RSA-2048
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDNAIHqeyrh6gbV
+n3xz2f+5SglhXC5Lp8Y2zvCN01M+wxhVJbAVx2m5mnfWclv5w1Mqm25fZifV+4UW
+B2jT3anL01l0URcX3D0wnS/EfuQfl+Mq23+d2GShxHZ6Zm7NcbwarPXnUX9LOFlP
+6psF5C1a2pkSAIAT5FMWpNm7jtCGuI0odYusr5ItRqhotIXSOcm66w4rZFknEPQr
+LR6gpLSALAvsqzKPimiwBzvbVG/uqYCdKEmRKzkMFTK8finHZY+BdfrkbzQzL/h7
+yrPkBkm5hXeGnaDqcYNT8HInVIhpE2SHYNEivmduD8SD3SD/wxvalqMZZsmqLnWt
+A95H4cRPAgMBAAECggEAYCl6x5kbFnoG1rJHWLjL4gi+ubLZ7Jc4vYD5Ci41AF3X
+ziktnim6iFvTFv7x8gkTvArJDWsICLJBTYIQREHYYkozzgIzyPeApIs3Wv8C12cS
+IopwJITbP56+zM+77hcJ26GCgA2Unp5CFuC/81WDiPi9kNo3Oh2CdD7D+90UJ/0W
+glplejFpEuhpU2URfKL4RckJQF/KxV+JX8FdIDhsJu54yemQdQKaF4psHkzwwgDo
+qc+yfp0Vb4bmwq3CKxqEoc1cpbJ5CHXXlAfISzUjlcuBzD/tW7BDtp7eDAcgRVAC
+XO6MX0QBcLYSC7SOD3R7zY9SIRCFDfBDxCjf0YcFMQKBgQD2+WG0fLwDXTrt68fe
+hQqVa2Xs25z2B2QGPxWqSFU8WNly/mZ1BW413f3De/O58vYi7icTNyVoScm+8hdv
+6PfD+LuRujdN1TuvPeyBTSvewQwf3IjN0Wh28mse36PwlBl+301C/x+ylxEDuJjK
+hZxCcocIaoQqtBC7ac8tNa9r4wKBgQDUfnJKf/QQSLJwwlJKQQGHi3MVm7c9PbwY
+eyIOY1s1NPluJDoYTZP4YLa/u2txwe2aHh9FhYMCPDAelqaSwaCLU9DsnKkQEA2A
+RR47fcagG6xK7O+N95iEa8I1oIy7os9MBoBMwRIZ6VYIxxTj8UMNSR+tu6MqV1Gg
+T5d0WDTJpQKBgCHyRSu5uV39AoyRS/eZ8cp36JqV1Q08FtOE+EVfi9evnrPfo9WR
+2YQt7yNfdjCo5IwIj/ZkLhAXlFNakz4el2+oUJ/HKLLaDEoaCNf883q6rh/zABrK
+HcG7sF2d/7qhoJ9/se7zgjfZ68zHIrkzhDbd5xGREnmMJoCcGo3sQyBhAoGAH3UQ
+qmLC2N5KPFMoJ4H0HgLQ6LQCrnhDLkScSBEBYaEUA/AtAYgKjcyTgVLXlyGkcRpg
+esRHHr+WSBD5W+R6ReYEmeKfTJdzyDdzQE9gZjdyjC0DUbsDwybIu3OnIef6VEDq
+IXK7oUZfzDDcsNn4mTDoFaoff5cpqFfgDgM43VkCgYBNHw11b+d+AQmaZS9QqIt7
+aF3FvwCYHV0jdv0Mb+Kc1bY4c0R5MFpzrTwVmdOerjuuA1+9b+0Hwo3nBZM4eaBu
+SOamA2hu2OJWCl9q8fLCT69KqWDjghhvFe7c6aJJGucwaA3Uz3eLcPqoaCarMiNH
+fMkTd7GabVourqIZdgvu1Q==
+-----END PRIVATE KEY-----
+
+# EC P-256 key
+
+PrivateKey = P-256
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgiocvtiiTxNH/xbnw
++RdYBp+DUuCPoFpJ+NuSbLVyhyWhRANCAAQsFQ9CnOcPIWwlLPXgYs4fY5zV0WXH
++JQkBywnGX14szuSDpXNtmTpkNzwz+oNlOKo5q+dDlgFbmUxBJJbn+bJ
+-----END PRIVATE KEY-----
+
+# RSA tests
+
+Sign = RSA-2048
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad
+
+Verify = RSA-2048
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad
+
+# Digest too long
+Sign = RSA-2048
+Digest = SHA1
+Input = "0123456789ABCDEF12345"
+Output =
+Error = INVALID_DIGEST_LENGTH
+
+# Digest too short
+Sign = RSA-2048
+Digest = SHA1
+Input = "0123456789ABCDEF12345"
+Output =
+Error = INVALID_DIGEST_LENGTH
+
+# Mismatched digest
+Verify = RSA-2048
+Digest = SHA1
+Input = "0123456789ABCDEF1233"
+Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad
+Error = BAD_SIGNATURE
+
+# Corrupted signature
+Verify = RSA-2048
+Digest = SHA1
+Input = "0123456789ABCDEF1233"
+Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ae
+Error = BLOCK_TYPE_IS_NOT_01
+
+# parameter missing (NOTE: this differs from upstream)
+Verify = RSA-2048
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = 3ec3fc29eb6e122bd7aa361cd09fe1bcbe85311096a7b9e4799cedfb2351ce0ab7fe4e75b4f6b37f67edd9c60c800f9ab941c0c157d7d880ca9de40c951d60fd293ae220d4bc510b1572d6e85a1bbbd8605b52e05f1c64fafdae59a1c2fbed214b7844d0134619de62851d5a0522e32e556e5950f3f97b8150e3f0dffee612c924201c27cd9bc8b423a71533380c276d3d59fcba35a2e80a1a192ec266a6c2255012cd86a349fe90a542b355fa3355b04da6cdf1df77f0e7bd44a90e880e1760266d233e465226f5db1c68857847d82072861ee266ddfc2e596845b77e1803274a579835ab5e4975d81d20b7df9cec7795489e4a2bdb8c1cf6a6b359945ac92c
+Error = BAD_SIGNATURE
+
+# embedded digest too long
+Verify = RSA-2048
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = afec9a0d5330a08f54283bb4a9d4e7e7e70fc1342336c4c766fba713f66970151c6e27413c48c33864ea45a0238787004f338ed3e21b53b0fe9c1151c42c388cbc7cba5a06b706c407a5b48324fbe994dc7afc3a19fb3d2841e66222596c14cd72a0f0a7455a019d8eb554f59c0183f9552b75aa96fee8bf935945e079ca283d2bd3534a86f11351f6d6181fbf433e5b01a6d1422145c7a72214d3aacdd5d3af12b2d6bf6438f9f9a64010d8aeed801c87f0859412b236150b86a545f7239be022f4a7ad246b59df87514294cb4a4c7c5a997ee53c66054d9f38ca4e76c1f7af83c30f737ef70f83a45aebe18238ddb95e1998814ca4fc72388f1533147c169d
+Error = BAD_SIGNATURE
+
+# embedded digest too short
+Verify = RSA-2048
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = afec9a0d5330a08f54283bb4a9d4e7e7e70fc1342336c4c766fba713f66970151c6e27413c48c33864ea45a0238787004f338ed3e21b53b0fe9c1151c42c388cbc7cba5a06b706c407a5b48324fbe994dc7afc3a19fb3d2841e66222596c14cd72a0f0a7455a019d8eb554f59c0183f9552b75aa96fee8bf935945e079ca283d2bd3534a86f11351f6d6181fbf433e5b01a6d1422145c7a72214d3aacdd5d3af12b2d6bf6438f9f9a64010d8aeed801c87f0859412b236150b86a545f7239be022f4a7ad246b59df87514294cb4a4c7c5a997ee53c66054d9f38ca4e76c1f7af83c30f737ef70f83a45aebe18238ddb95e1998814ca4fc72388f1533147c169d
+Error = BAD_SIGNATURE
+
+# Garbage after DigestInfo
+Verify = RSA-2048
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = 9ee34872d4271a7d8808af0a4052a145a6d6a8437d00da3ed14428c7f087cd39f4d43334c41af63e7fa1ba363fee7bcef401d9d36a662abbab55ce89a696e1be0dfa19a5d09ca617dd488787b6048baaefeb29bc8688b2fe3882de2b77c905b5a8b56cf9616041e5ec934ba6de863efe93acc4eef783fe7f72a00fa65d6093ed32bf98ce527e62ccb1d56317f4be18b7e0f55d7c36617d2d0678a306e3350956b662ac15df45215dd8f6b314babb9788e6c272fa461e4c9b512a11a4b92bc77c3a4c95c903fccb238794eca5c750477bf56ea6ee6a167367d881b485ae3889e7c489af8fdf38e0c0f2aed780831182e34abedd43c39281b290774bf35cc25274
+Error = BAD_SIGNATURE
+
+# invalid tag for parameter
+Verify = RSA-2048
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = 49525db4d44c755e560cba980b1d85ea604b0e077fcadd4ba44072a3487bbddb835016200a7d8739cce2dc3223d9c20cbdd25059ab02277f1f21318efd18e21038ec89aa9d40680987129e8b41ba33bceb86518bdf47268b921cce2037acabca6575d832499538d6f40cdba0d40bd7f4d8ea6ca6e2eec87f294efc971407857f5d7db09f6a7b31e301f571c6d82a5e3d08d2bb3a36e673d28b910f5bec57f0fcc4d968fd7c94d0b9226dec17f5192ad8b42bcab6f26e1bea1fdc3b958199acb00f14ebcb2a352f3afcedd4c09000128a603bbeb9696dea13040445253972d46237a25c7845e3b464e6984c2348ea1f1210a9ff0b00d2d72b50db00c009bb39f9
+Error = BAD_SIGNATURE
+
+# EC tests
+
+Verify = P-256
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8
+
+# Digest too long
+Verify = P-256
+Digest = SHA1
+Input = "0123456789ABCDEF12345"
+Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8
+# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced.
+Error = public key routines
+
+# Digest too short
+Verify = P-256
+Digest = SHA1
+Input = "0123456789ABCDEF123"
+Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8
+# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced.
+Error = public key routines
+
+# Digest invalid
+Verify = P-256
+Digest = SHA1
+Input = "0123456789ABCDEF1235"
+Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8
+# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced.
+Error = public key routines
+
+# Invalid signature
+Verify = P-256
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec7
+# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced.
+Error = public key routines
+
+# Garbage after signature
+Verify = P-256
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec800
+# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced.
+Error = public key routines
+
+# BER signature
+Verify = P-256
+Digest = SHA1
+Input = "0123456789ABCDEF1234"
+Output = 3080022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec80000
+# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced.
+Error = public key routines
diff --git a/src/crypto/evp/internal.h b/src/crypto/evp/internal.h
index 2b0f608..08a7bfb 100644
--- a/src/crypto/evp/internal.h
+++ b/src/crypto/evp/internal.h
@@ -170,8 +170,49 @@ typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
#define EVP_PKEY_OP_TYPE_GEN (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
+/* EVP_PKEY_CTX_ctrl performs |cmd| on |ctx|. The |keytype| and |optype|
+ * arguments can be -1 to specify that any type and operation are acceptable,
+ * otherwise |keytype| must match the type of |ctx| and the bits of |optype|
+ * must intersect the operation flags set on |ctx|.
+ *
+ * The |p1| and |p2| arguments depend on the value of |cmd|.
+ *
+ * It returns one on success and zero on error. */
+OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
+ int cmd, int p1, void *p2);
+
+/* EVP_PKEY_CTRL_DIGESTINIT is an internal value. It's called by
+ * EVP_DigestInit_ex to signal the |EVP_PKEY| that a digest operation is
+ * starting.
+ *
+ * TODO(davidben): This is only needed to support the deprecated HMAC |EVP_PKEY|
+ * types. */
+#define EVP_PKEY_CTRL_DIGESTINIT 3
+
+/* EVP_PKEY_CTRL_PEER_KEY is called with different values of |p1|:
+ * 0: Is called from |EVP_PKEY_derive_set_peer| and |p2| contains a peer key.
+ * If the return value is <= 0, the key is rejected.
+ * 1: Is called at the end of |EVP_PKEY_derive_set_peer| and |p2| contains a
+ * peer key. If the return value is <= 0, the key is rejected.
+ * 2: Is called with |p2| == NULL to test whether the peer's key was used.
+ * (EC)DH always return one in this case.
+ * 3: Is called with |p2| == NULL to set whether the peer's key was used.
+ * (EC)DH always return one in this case. This was only used for GOST. */
+#define EVP_PKEY_CTRL_PEER_KEY 4
+
+/* EVP_PKEY_CTRL_SET_MAC_KEY sets a MAC key. For example, this can be done an
+ * |EVP_PKEY_CTX| prior to calling |EVP_PKEY_keygen| in order to generate an
+ * HMAC |EVP_PKEY| with the given key. It returns one on success and zero on
+ * error. */
+#define EVP_PKEY_CTRL_SET_MAC_KEY 5
+
+/* EVP_PKEY_ALG_CTRL is the base value from which key-type specific ctrl
+ * commands are numbered. */
+#define EVP_PKEY_ALG_CTRL 0x1000
+
#define EVP_PKEY_CTRL_MD 1
#define EVP_PKEY_CTRL_GET_MD 2
+
#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1)
#define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 2)
#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 3)
@@ -185,6 +226,8 @@ typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
#define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 11)
#define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12)
+#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1)
+
struct evp_pkey_ctx_st {
/* Method associated with this operation */
const EVP_PKEY_METHOD *pmeth;
diff --git a/src/crypto/evp/p_dsa_asn1.c b/src/crypto/evp/p_dsa_asn1.c
new file mode 100644
index 0000000..0ac7da7
--- /dev/null
+++ b/src/crypto/evp/p_dsa_asn1.c
@@ -0,0 +1,569 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com). */
+
+#include <openssl/evp.h>
+
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/digest.h>
+#include <openssl/dsa.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/obj.h>
+#include <openssl/x509.h>
+
+#include "../dsa/internal.h"
+#include "internal.h"
+
+
+static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
+ const uint8_t *p, *pm;
+ int pklen, pmlen;
+ int ptype;
+ void *pval;
+ ASN1_STRING *pstr;
+ X509_ALGOR *palg;
+ ASN1_INTEGER *public_key = NULL;
+
+ DSA *dsa = NULL;
+
+ if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) {
+ return 0;
+ }
+ X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+ if (ptype == V_ASN1_SEQUENCE) {
+ pstr = pval;
+ pm = pstr->data;
+ pmlen = pstr->length;
+
+ dsa = d2i_DSAparams(NULL, &pm, pmlen);
+ if (dsa == NULL) {
+ OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_DECODE_ERROR);
+ goto err;
+ }
+ } else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) {
+ dsa = DSA_new();
+ if (dsa == NULL) {
+ OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ } else {
+ OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_PARAMETER_ENCODING_ERROR);
+ goto err;
+ }
+
+ public_key = d2i_ASN1_INTEGER(NULL, &p, pklen);
+ if (public_key == NULL) {
+ OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_DECODE_ERROR);
+ goto err;
+ }
+
+ dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL);
+ if (dsa->pub_key == NULL) {
+ OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_BN_DECODE_ERROR);
+ goto err;
+ }
+
+ ASN1_INTEGER_free(public_key);
+ EVP_PKEY_assign_DSA(pkey, dsa);
+ return 1;
+
+err:
+ ASN1_INTEGER_free(public_key);
+ DSA_free(dsa);
+ return 0;
+}
+
+static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
+ DSA *dsa;
+ void *pval = NULL;
+ uint8_t *penc = NULL;
+ int penclen;
+
+ dsa = pkey->pkey.dsa;
+ dsa->write_params = 0;
+
+ penclen = i2d_DSAPublicKey(dsa, &penc);
+
+ if (penclen <= 0) {
+ OPENSSL_PUT_ERROR(EVP, dsa_pub_encode, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), V_ASN1_UNDEF, pval,
+ penc, penclen)) {
+ return 1;
+ }
+
+err:
+ OPENSSL_free(penc);
+ ASN1_STRING_free(pval);
+
+ return 0;
+}
+
+static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
+ const uint8_t *p, *pm;
+ int pklen, pmlen;
+ int ptype;
+ void *pval;
+ ASN1_STRING *pstr;
+ X509_ALGOR *palg;
+ ASN1_INTEGER *privkey = NULL;
+ BN_CTX *ctx = NULL;
+
+ /* In PKCS#8 DSA: you just get a private key integer and parameters in the
+ * AlgorithmIdentifier the pubkey must be recalculated. */
+
+ STACK_OF(ASN1_TYPE) *ndsa = NULL;
+ DSA *dsa = NULL;
+
+ if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) {
+ return 0;
+ }
+ X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+ /* Check for broken DSA PKCS#8, UGH! */
+ if (*p == (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) {
+ ASN1_TYPE *t1, *t2;
+ ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen);
+ if (ndsa == NULL) {
+ goto decerr;
+ }
+ if (sk_ASN1_TYPE_num(ndsa) != 2) {
+ goto decerr;
+ }
+
+ /* Handle Two broken types:
+ * SEQUENCE {parameters, priv_key}
+ * SEQUENCE {pub_key, priv_key}. */
+
+ t1 = sk_ASN1_TYPE_value(ndsa, 0);
+ t2 = sk_ASN1_TYPE_value(ndsa, 1);
+ if (t1->type == V_ASN1_SEQUENCE) {
+ p8->broken = PKCS8_EMBEDDED_PARAM;
+ pval = t1->value.ptr;
+ } else if (ptype == V_ASN1_SEQUENCE) {
+ p8->broken = PKCS8_NS_DB;
+ } else {
+ goto decerr;
+ }
+
+ if (t2->type != V_ASN1_INTEGER) {
+ goto decerr;
+ }
+
+ privkey = t2->value.integer;
+ } else {
+ const uint8_t *q = p;
+ privkey = d2i_ASN1_INTEGER(NULL, &p, pklen);
+ if (privkey == NULL) {
+ goto decerr;
+ }
+ if (privkey->type == V_ASN1_NEG_INTEGER) {
+ p8->broken = PKCS8_NEG_PRIVKEY;
+ ASN1_INTEGER_free(privkey);
+ privkey = d2i_ASN1_UINTEGER(NULL, &q, pklen);
+ if (privkey == NULL) {
+ goto decerr;
+ }
+ }
+ if (ptype != V_ASN1_SEQUENCE) {
+ goto decerr;
+ }
+ }
+
+ pstr = pval;
+ pm = pstr->data;
+ pmlen = pstr->length;
+ dsa = d2i_DSAparams(NULL, &pm, pmlen);
+ if (dsa == NULL) {
+ goto decerr;
+ }
+ /* We have parameters. Now set private key */
+ dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL);
+ if (dsa->priv_key == NULL) {
+ OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_LIB_BN);
+ goto dsaerr;
+ }
+ /* Calculate public key. */
+ dsa->pub_key = BN_new();
+ if (dsa->pub_key == NULL) {
+ OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_R_MALLOC_FAILURE);
+ goto dsaerr;
+ }
+ ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_R_MALLOC_FAILURE);
+ goto dsaerr;
+ }
+
+ if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
+ OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_LIB_BN);
+ goto dsaerr;
+ }
+
+ EVP_PKEY_assign_DSA(pkey, dsa);
+ BN_CTX_free(ctx);
+ sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
+ ASN1_INTEGER_free(privkey);
+
+ return 1;
+
+decerr:
+ OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, EVP_R_DECODE_ERROR);
+
+dsaerr:
+ BN_CTX_free(ctx);
+ ASN1_INTEGER_free(privkey);
+ sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
+ DSA_free(dsa);
+ return 0;
+}
+
+static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
+ ASN1_STRING *params = NULL;
+ ASN1_INTEGER *prkey = NULL;
+ uint8_t *dp = NULL;
+ int dplen;
+
+ if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) {
+ OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, EVP_R_MISSING_PARAMETERS);
+ goto err;
+ }
+
+ params = ASN1_STRING_new();
+ if (!params) {
+ OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
+ if (params->length <= 0) {
+ OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ params->type = V_ASN1_SEQUENCE;
+
+ /* Get private key into integer. */
+ prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
+
+ if (!prkey) {
+ OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, ERR_LIB_BN);
+ goto err;
+ }
+
+ dplen = i2d_ASN1_INTEGER(prkey, &dp);
+
+ ASN1_INTEGER_free(prkey);
+
+ if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_dsa), 0,
+ V_ASN1_SEQUENCE, params, dp, dplen)) {
+ goto err;
+ }
+
+ return 1;
+
+err:
+ OPENSSL_free(dp);
+ ASN1_STRING_free(params);
+ ASN1_INTEGER_free(prkey);
+ return 0;
+}
+
+static int int_dsa_size(const EVP_PKEY *pkey) {
+ return DSA_size(pkey->pkey.dsa);
+}
+
+static int dsa_bits(const EVP_PKEY *pkey) {
+ return BN_num_bits(pkey->pkey.dsa->p);
+}
+
+static int dsa_missing_parameters(const EVP_PKEY *pkey) {
+ DSA *dsa;
+ dsa = pkey->pkey.dsa;
+ if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
+ return 1;
+ }
+ return 0;
+}
+
+static int dup_bn_into(BIGNUM **out, BIGNUM *src) {
+ BIGNUM *a;
+
+ a = BN_dup(src);
+ if (a == NULL) {
+ return 0;
+ }
+ BN_free(*out);
+ *out = a;
+
+ return 1;
+}
+
+static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) {
+ if (!dup_bn_into(&to->pkey.dsa->p, from->pkey.dsa->p) ||
+ !dup_bn_into(&to->pkey.dsa->q, from->pkey.dsa->q) ||
+ !dup_bn_into(&to->pkey.dsa->g, from->pkey.dsa->g)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) {
+ return BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) == 0 &&
+ BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) == 0 &&
+ BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g) == 0;
+}
+
+static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
+ return BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) == 0;
+}
+
+static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); }
+
+static void update_buflen(const BIGNUM *b, size_t *pbuflen) {
+ size_t i;
+
+ if (!b) {
+ return;
+ }
+ i = BN_num_bytes(b);
+ if (*pbuflen < i) {
+ *pbuflen = i;
+ }
+}
+
+static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) {
+ uint8_t *m = NULL;
+ int ret = 0;
+ size_t buf_len = 0;
+ const char *ktype = NULL;
+
+ const BIGNUM *priv_key, *pub_key;
+
+ priv_key = NULL;
+ if (ptype == 2) {
+ priv_key = x->priv_key;
+ }
+
+ pub_key = NULL;
+ if (ptype > 0) {
+ pub_key = x->pub_key;
+ }
+
+ ktype = "DSA-Parameters";
+ if (ptype == 2) {
+ ktype = "Private-Key";
+ } else if (ptype == 1) {
+ ktype = "Public-Key";
+ }
+
+ update_buflen(x->p, &buf_len);
+ update_buflen(x->q, &buf_len);
+ update_buflen(x->g, &buf_len);
+ update_buflen(priv_key, &buf_len);
+ update_buflen(pub_key, &buf_len);
+
+ m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
+ if (m == NULL) {
+ OPENSSL_PUT_ERROR(EVP, do_dsa_print, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (priv_key) {
+ if (!BIO_indent(bp, off, 128) ||
+ BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) {
+ goto err;
+ }
+ }
+
+ if (!ASN1_bn_print(bp, "priv:", priv_key, m, off) ||
+ !ASN1_bn_print(bp, "pub: ", pub_key, m, off) ||
+ !ASN1_bn_print(bp, "P: ", x->p, m, off) ||
+ !ASN1_bn_print(bp, "Q: ", x->q, m, off) ||
+ !ASN1_bn_print(bp, "G: ", x->g, m, off)) {
+ goto err;
+ }
+ ret = 1;
+
+err:
+ OPENSSL_free(m);
+ return ret;
+}
+
+static int dsa_param_decode(EVP_PKEY *pkey, const uint8_t **pder, int derlen) {
+ DSA *dsa;
+ dsa = d2i_DSAparams(NULL, pder, derlen);
+ if (dsa == NULL) {
+ OPENSSL_PUT_ERROR(EVP, dsa_param_decode, ERR_R_DSA_LIB);
+ return 0;
+ }
+ EVP_PKEY_assign_DSA(pkey, dsa);
+ return 1;
+}
+
+static int dsa_param_encode(const EVP_PKEY *pkey, uint8_t **pder) {
+ return i2d_DSAparams(pkey->pkey.dsa, pder);
+}
+
+static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx) {
+ return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
+}
+
+static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx) {
+ return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
+}
+
+static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+ ASN1_PCTX *ctx) {
+ return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
+}
+
+static int old_dsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
+ int derlen) {
+ DSA *dsa;
+ dsa = d2i_DSAPrivateKey(NULL, pder, derlen);
+ if (dsa == NULL) {
+ OPENSSL_PUT_ERROR(EVP, old_dsa_priv_decode, ERR_R_DSA_LIB);
+ return 0;
+ }
+ EVP_PKEY_assign_DSA(pkey, dsa);
+ return 1;
+}
+
+static int old_dsa_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) {
+ return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
+}
+
+static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
+ const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) {
+ DSA_SIG *dsa_sig;
+ const uint8_t *p;
+
+ if (!sig) {
+ return BIO_puts(bp, "\n") > 0;
+ }
+
+ p = sig->data;
+ dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
+ if (dsa_sig == NULL) {
+ return X509_signature_dump(bp, sig, indent);
+ }
+
+ int rv = 0;
+ size_t buf_len = 0;
+ uint8_t *m = NULL;
+
+ update_buflen(dsa_sig->r, &buf_len);
+ update_buflen(dsa_sig->s, &buf_len);
+ m = OPENSSL_malloc(buf_len + 10);
+ if (m == NULL) {
+ OPENSSL_PUT_ERROR(EVP, dsa_sig_print, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (BIO_write(bp, "\n", 1) != 1 ||
+ !ASN1_bn_print(bp, "r: ", dsa_sig->r, m, indent) ||
+ !ASN1_bn_print(bp, "s: ", dsa_sig->s, m, indent)) {
+ goto err;
+ }
+ rv = 1;
+
+err:
+ OPENSSL_free(m);
+ DSA_SIG_free(dsa_sig);
+ return rv;
+}
+
+const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = {
+ EVP_PKEY_DSA,
+ EVP_PKEY_DSA,
+ 0,
+
+ "DSA",
+ "OpenSSL DSA method",
+
+ dsa_pub_decode,
+ dsa_pub_encode,
+ dsa_pub_cmp,
+ dsa_pub_print,
+
+ dsa_priv_decode,
+ dsa_priv_encode,
+ dsa_priv_print,
+
+ NULL /* pkey_opaque */,
+ NULL /* pkey_supports_digest */,
+
+ int_dsa_size,
+ dsa_bits,
+
+ dsa_param_decode,
+ dsa_param_encode,
+ dsa_missing_parameters,
+ dsa_copy_parameters,
+ dsa_cmp_parameters,
+ dsa_param_print,
+ dsa_sig_print,
+
+ int_dsa_free,
+ old_dsa_priv_decode,
+ old_dsa_priv_encode,
+};
diff --git a/src/crypto/evp/p_ec.c b/src/crypto/evp/p_ec.c
index c274131..73c00d8 100644
--- a/src/crypto/evp/p_ec.c
+++ b/src/crypto/evp/p_ec.c
@@ -119,9 +119,7 @@ static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) {
return;
}
- if (dctx->gen_group) {
- EC_GROUP_free(dctx->gen_group);
- }
+ EC_GROUP_free(dctx->gen_group);
OPENSSL_free(dctx);
}
@@ -212,8 +210,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
OPENSSL_PUT_ERROR(EVP, pkey_ec_ctrl, EVP_R_INVALID_CURVE);
return 0;
}
- if (dctx->gen_group)
- EC_GROUP_free(dctx->gen_group);
+ EC_GROUP_free(dctx->gen_group);
dctx->gen_group = group;
return 1;
@@ -240,7 +237,8 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
return 1;
default:
- return -2;
+ OPENSSL_PUT_ERROR(EVP, pkey_ec_ctrl, EVP_R_COMMAND_NOT_SUPPORTED);
+ return 0;
}
}
diff --git a/src/crypto/evp/p_ec_asn1.c b/src/crypto/evp/p_ec_asn1.c
index 914cc2f..fbbf4e7 100644
--- a/src/crypto/evp/p_ec_asn1.c
+++ b/src/crypto/evp/p_ec_asn1.c
@@ -142,23 +142,13 @@ static EC_KEY *eckey_type2param(int ptype, void *pval) {
}
} else if (ptype == V_ASN1_OBJECT) {
ASN1_OBJECT *poid = pval;
- EC_GROUP *group;
/* type == V_ASN1_OBJECT => the parameters are given
* by an asn1 OID */
- eckey = EC_KEY_new();
+ eckey = EC_KEY_new_by_curve_name(OBJ_obj2nid(poid));
if (eckey == NULL) {
- OPENSSL_PUT_ERROR(EVP, eckey_type2param, ERR_R_MALLOC_FAILURE);
goto err;
}
- group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
- if (group == NULL) {
- goto err;
- }
- if (EC_KEY_set_group(eckey, group) == 0) {
- goto err;
- }
- EC_GROUP_free(group);
} else {
OPENSSL_PUT_ERROR(EVP, eckey_type2param, EVP_R_DECODE_ERROR);
goto err;
@@ -201,8 +191,9 @@ static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
return 1;
err:
- if (eckey)
+ if (eckey) {
EC_KEY_free(eckey);
+ }
return 0;
}
@@ -235,8 +226,9 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
eckey = eckey_type2param(ptype, pval);
- if (!eckey)
+ if (!eckey) {
goto ecliberr;
+ }
/* We have parameters now set private key */
if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
@@ -282,8 +274,9 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
ecliberr:
OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
ecerr:
- if (eckey)
+ if (eckey) {
EC_KEY_free(eckey);
+ }
return 0;
}
@@ -439,10 +432,12 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
if (ktype == 2) {
priv_key = EC_KEY_get0_private_key(x);
- if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len)
+ if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) {
buf_len = i;
- } else
+ }
+ } else {
priv_key = NULL;
+ }
if (ktype > 0) {
buf_len += 10;
@@ -451,24 +446,27 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
goto err;
}
}
- if (ktype == 2)
+ if (ktype == 2) {
ecstr = "Private-Key";
- else if (ktype == 1)
+ } else if (ktype == 1) {
ecstr = "Public-Key";
- else
+ } else {
ecstr = "ECDSA-Parameters";
+ }
- if (!BIO_indent(bp, off, 128))
- goto err;
- if ((order = BN_new()) == NULL)
- goto err;
- if (!EC_GROUP_get_order(group, order, NULL))
+ if (!BIO_indent(bp, off, 128)) {
goto err;
- if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0)
+ }
+ order = BN_new();
+ if (order == NULL || !EC_GROUP_get_order(group, order, NULL) ||
+ BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
goto err;
+ }
- if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, buffer, off))
+ if ((priv_key != NULL) &&
+ !ASN1_bn_print(bp, "priv:", priv_key, buffer, off)) {
goto err;
+ }
if (pub_key_bytes != NULL) {
BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
}
@@ -479,16 +477,13 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
ret = 1;
err:
- if (!ret)
+ if (!ret) {
OPENSSL_PUT_ERROR(EVP, do_EC_KEY_print, reason);
- if (pub_key_bytes)
- OPENSSL_free(pub_key_bytes);
- if (order)
- BN_free(order);
- if (ctx)
- BN_CTX_free(ctx);
- if (buffer != NULL)
- OPENSSL_free(buffer);
+ }
+ OPENSSL_free(pub_key_bytes);
+ BN_free(order);
+ BN_CTX_free(ctx);
+ OPENSSL_free(buffer);
return ret;
}
diff --git a/src/crypto/evp/p_hmac.c b/src/crypto/evp/p_hmac.c
index 6d9a909..21703ed 100644
--- a/src/crypto/evp/p_hmac.c
+++ b/src/crypto/evp/p_hmac.c
@@ -204,7 +204,8 @@ static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
break;
default:
- return -2;
+ OPENSSL_PUT_ERROR(EVP, pkey_hmac_ctrl, EVP_R_COMMAND_NOT_SUPPORTED);
+ return 0;
}
return 1;
}
diff --git a/src/crypto/evp/p_rsa.c b/src/crypto/evp/p_rsa.c
index 31f5aaa..5abc075 100644
--- a/src/crypto/evp/p_rsa.c
+++ b/src/crypto/evp/p_rsa.c
@@ -55,10 +55,12 @@
#include <openssl/evp.h>
+#include <limits.h>
#include <string.h>
#include <openssl/bn.h>
#include <openssl/buf.h>
+#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -125,9 +127,7 @@ static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) {
dctx->md = sctx->md;
dctx->mgf1md = sctx->mgf1md;
if (sctx->oaep_label) {
- if (dctx->oaep_label) {
- OPENSSL_free(dctx->oaep_label);
- }
+ OPENSSL_free(dctx->oaep_label);
dctx->oaep_label = BUF_memdup(sctx->oaep_label, sctx->oaep_labellen);
if (!dctx->oaep_label) {
return 0;
@@ -145,15 +145,9 @@ static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) {
return;
}
- if (rctx->pub_exp) {
- BN_free(rctx->pub_exp);
- }
- if (rctx->tbuf) {
- OPENSSL_free(rctx->tbuf);
- }
- if (rctx->oaep_label) {
- OPENSSL_free(rctx->oaep_label);
- }
+ BN_free(rctx->pub_exp);
+ OPENSSL_free(rctx->tbuf);
+ OPENSSL_free(rctx->oaep_label);
OPENSSL_free(rctx);
}
@@ -369,7 +363,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
0 == (ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))) {
OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl,
EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
- return -2;
+ return 0;
}
if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) &&
rctx->md == NULL) {
@@ -386,13 +380,13 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) {
OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PSS_SALTLEN);
- return -2;
+ return 0;
}
if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) {
*(int *)p2 = rctx->saltlen;
} else {
if (p1 < -2) {
- return -2;
+ return 0;
}
rctx->saltlen = p1;
}
@@ -401,14 +395,14 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
if (p1 < 256) {
OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_KEYBITS);
- return -2;
+ return 0;
}
rctx->nbits = p1;
return 1;
case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
if (!p2) {
- return -2;
+ return 0;
}
BN_free(rctx->pub_exp);
rctx->pub_exp = p2;
@@ -418,7 +412,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE);
- return -2;
+ return 0;
}
if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) {
*(const EVP_MD **)p2 = rctx->md;
@@ -443,7 +437,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING &&
rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_MGF1_MD);
- return -2;
+ return 0;
}
if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) {
if (rctx->mgf1md) {
@@ -459,11 +453,9 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE);
- return -2;
- }
- if (rctx->oaep_label) {
- OPENSSL_free(rctx->oaep_label);
+ return 0;
}
+ OPENSSL_free(rctx->oaep_label);
if (p2 && p1 > 0) {
/* TODO(fork): this seems wrong. Shouldn't it take a copy of the
* buffer? */
@@ -478,16 +470,17 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE);
- return -2;
+ return 0;
}
- *(uint8_t **)p2 = rctx->oaep_label;
- return rctx->oaep_labellen;
+ CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen);
+ return 1;
case EVP_PKEY_CTRL_DIGESTINIT:
return 1;
default:
- return -2;
+ OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_COMMAND_NOT_SUPPORTED);
+ return 0;
}
}
@@ -497,8 +490,9 @@ static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
if (!rctx->pub_exp) {
rctx->pub_exp = BN_new();
- if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4))
+ if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) {
return 0;
+ }
}
rsa = RSA_new();
if (!rsa) {
@@ -583,7 +577,7 @@ int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, const uint8_t *label,
size_t label_len) {
int label_len_int = label_len;
if (((size_t) label_len_int) != label_len) {
- return -2;
+ return 0;
}
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
@@ -593,6 +587,15 @@ int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, const uint8_t *label,
int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
const uint8_t **out_label) {
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
- EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *) out_label);
+ CBS label;
+ if (!EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
+ EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, &label)) {
+ return -1;
+ }
+ if (CBS_len(&label) > INT_MAX) {
+ OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_get0_rsa_oaep_label, ERR_R_OVERFLOW);
+ return -1;
+ }
+ *out_label = CBS_data(&label);
+ return (int)CBS_len(&label);
}
diff --git a/src/crypto/evp/p_rsa_asn1.c b/src/crypto/evp/p_rsa_asn1.c
index f478d50..1e2d3f6 100644
--- a/src/crypto/evp/p_rsa_asn1.c
+++ b/src/crypto/evp/p_rsa_asn1.c
@@ -245,9 +245,7 @@ static int do_rsa_print(BIO *out, const RSA *rsa, int off,
ret = 1;
err:
- if (m != NULL) {
- OPENSSL_free(m);
- }
+ OPENSSL_free(m);
return ret;
}
@@ -394,12 +392,8 @@ static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
pss = rsa_pss_decode(sigalg, &maskHash);
rv = rsa_pss_param_print(bp, pss, maskHash, indent);
- if (pss) {
- RSA_PSS_PARAMS_free(pss);
- }
- if (maskHash) {
- X509_ALGOR_free(maskHash);
- }
+ RSA_PSS_PARAMS_free(pss);
+ X509_ALGOR_free(maskHash);
if (!rv) {
return 0;
}
@@ -463,12 +457,11 @@ static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) {
stmp = NULL;
err:
- if (stmp)
- ASN1_STRING_free(stmp);
- if (algtmp)
- X509_ALGOR_free(algtmp);
- if (*palg)
+ ASN1_STRING_free(stmp);
+ X509_ALGOR_free(algtmp);
+ if (*palg) {
return 1;
+ }
return 0;
}
@@ -518,8 +511,8 @@ static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) {
EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
int saltlen, rv = 0;
- if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0 ||
- EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0 ||
+ if (!EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) ||
+ !EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) ||
!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) {
goto err;
}
@@ -560,12 +553,15 @@ static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) {
rv = 1;
err:
- if (pss)
+ if (pss) {
RSA_PSS_PARAMS_free(pss);
- if (rv)
+ }
+ if (rv) {
return os;
- if (os)
+ }
+ if (os) {
ASN1_STRING_free(os);
+ }
return NULL;
}
@@ -619,9 +615,9 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
}
if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey) ||
- EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0 ||
- EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0 ||
- EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) {
+ !EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) ||
+ !EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) ||
+ !EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md)) {
goto err;
}
@@ -653,7 +649,7 @@ static evp_digest_sign_algorithm_result_t rsa_digest_sign_algorithm(
EVP_MD_CTX *ctx, X509_ALGOR *sigalg) {
int pad_mode;
EVP_PKEY_CTX *pkctx = ctx->pctx;
- if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) {
+ if (!EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode)) {
return EVP_DIGEST_SIGN_ALGORITHM_ERROR;
}
if (pad_mode == RSA_PKCS1_PSS_PADDING) {
diff --git a/src/crypto/evp/pbkdf_test.cc b/src/crypto/evp/pbkdf_test.cc
new file mode 100644
index 0000000..ae2f405
--- /dev/null
+++ b/src/crypto/evp/pbkdf_test.cc
@@ -0,0 +1,179 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/bio.h>
+#include <openssl/crypto.h>
+#include <openssl/digest.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+
+// Prints out the data buffer as a sequence of hex bytes.
+static void PrintDataHex(const void *data, size_t len) {
+ for (size_t i = 0; i < len; ++i) {
+ fprintf(stderr, "%02x", (int)((const uint8_t *)data)[i]);
+ }
+}
+
+// Helper for testing that PBKDF2 derives the expected key from the given
+// inputs. Returns 1 on success, 0 otherwise.
+static bool TestPBKDF2(const void *password, size_t password_len,
+ const void *salt, size_t salt_len, unsigned iterations,
+ const EVP_MD *digest, size_t key_len,
+ const uint8_t *expected_key) {
+ uint8_t key[64];
+
+ if (key_len > sizeof(key)) {
+ fprintf(stderr, "Output buffer is not large enough.\n");
+ return false;
+ }
+
+ if (!PKCS5_PBKDF2_HMAC((const char *)password, password_len,
+ (const uint8_t *)salt, salt_len, iterations, digest,
+ key_len, key)) {
+ fprintf(stderr, "Call to PKCS5_PBKDF2_HMAC failed\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (memcmp(key, expected_key, key_len) != 0) {
+ fprintf(stderr, "Resulting key material does not match expectation\n");
+ fprintf(stderr, "Expected:\n ");
+ PrintDataHex(expected_key, key_len);
+ fprintf(stderr, "\nActual:\n ");
+ PrintDataHex(key, key_len);
+ fprintf(stderr, "\n");
+ return false;
+ }
+
+ return true;
+}
+
+// Tests deriving a key using an empty password (specified both as NULL and as
+// non-NULL). Note that NULL has special meaning to HMAC initialization.
+static bool TestEmptyPassword() {
+ const uint8_t kKey[] = {0xa3, 0x3d, 0xdd, 0xc3, 0x04, 0x78, 0x18,
+ 0x55, 0x15, 0x31, 0x1f, 0x87, 0x52, 0x89,
+ 0x5d, 0x36, 0xea, 0x43, 0x63, 0xa2};
+
+ if (!TestPBKDF2(NULL, 0, "salt", 4, 1, EVP_sha1(), sizeof(kKey), kKey) ||
+ !TestPBKDF2("", 0, "salt", 4, 1, EVP_sha1(), sizeof(kKey), kKey)) {
+ return false;
+ }
+
+ return true;
+}
+
+// Tests deriving a key using an empty salt. Note that the expectation was
+// generated using OpenSSL itself, and hence is not verified.
+static bool TestEmptySalt() {
+ const uint8_t kKey[] = {0x8b, 0xc2, 0xf9, 0x16, 0x7a, 0x81, 0xcd, 0xcf,
+ 0xad, 0x12, 0x35, 0xcd, 0x90, 0x47, 0xf1, 0x13,
+ 0x62, 0x71, 0xc1, 0xf9, 0x78, 0xfc, 0xfc, 0xb3,
+ 0x5e, 0x22, 0xdb, 0xea, 0xfa, 0x46, 0x34, 0xf6};
+
+ if (!TestPBKDF2("password", 8, NULL, 0, 2, EVP_sha256(), sizeof(kKey),
+ kKey) ||
+ !TestPBKDF2("password", 8, "", 0, 2, EVP_sha256(), sizeof(kKey), kKey)) {
+ return false;
+ }
+
+ return true;
+}
+
+// Exercises test vectors taken from https://tools.ietf.org/html/rfc6070.
+// Note that each of these test vectors uses SHA-1 as the digest.
+static bool TestRFC6070Vectors() {
+ const uint8_t kKey1[] = {0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e,
+ 0x71, 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60,
+ 0x12, 0x06, 0x2f, 0xe0, 0x37, 0xa6};
+ const uint8_t kKey2[] = {0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f,
+ 0x8c, 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d,
+ 0x41, 0xf0, 0xd8, 0xde, 0x89, 0x57};
+ const uint8_t kKey3[] = {0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
+ 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3};
+
+ if (!TestPBKDF2("password", 8, "salt", 4, 1, EVP_sha1(), sizeof(kKey1),
+ kKey1) ||
+ !TestPBKDF2("password", 8, "salt", 4, 2, EVP_sha1(), sizeof(kKey2),
+ kKey2) ||
+ !TestPBKDF2("pass\0word", 9, "sa\0lt", 5, 4096, EVP_sha1(),
+ sizeof(kKey3), kKey3)) {
+ return false;
+ }
+
+ return true;
+}
+
+// Tests key derivation using SHA-2 digests.
+static bool TestSHA2() {
+ // This test was taken from:
+ // http://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors.
+ const uint8_t kKey1[] = {0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3,
+ 0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0,
+ 0x2a, 0x30, 0x3f, 0x8e, 0xf3, 0xc2, 0x51, 0xdf,
+ 0xd6, 0xe2, 0xd8, 0x5a, 0x95, 0x47, 0x4c, 0x43};
+
+ // This test was taken from:
+ // http://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors.
+ const uint8_t kKey2[] = {
+ 0x8c, 0x05, 0x11, 0xf4, 0xc6, 0xe5, 0x97, 0xc6, 0xac, 0x63, 0x15,
+ 0xd8, 0xf0, 0x36, 0x2e, 0x22, 0x5f, 0x3c, 0x50, 0x14, 0x95, 0xba,
+ 0x23, 0xb8, 0x68, 0xc0, 0x05, 0x17, 0x4d, 0xc4, 0xee, 0x71, 0x11,
+ 0x5b, 0x59, 0xf9, 0xe6, 0x0c, 0xd9, 0x53, 0x2f, 0xa3, 0x3e, 0x0f,
+ 0x75, 0xae, 0xfe, 0x30, 0x22, 0x5c, 0x58, 0x3a, 0x18, 0x6c, 0xd8,
+ 0x2b, 0xd4, 0xda, 0xea, 0x97, 0x24, 0xa3, 0xd3, 0xb8};
+
+ if (!TestPBKDF2("password", 8, "salt", 4, 2, EVP_sha256(), sizeof(kKey1),
+ kKey1) ||
+ !TestPBKDF2("passwordPASSWORDpassword", 24,
+ "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, 4096,
+ EVP_sha512(), sizeof(kKey2), kKey2)) {
+ return false;
+ }
+
+ return true;
+}
+
+int main(void) {
+ CRYPTO_library_init();
+ ERR_load_crypto_strings();
+
+ if (!TestEmptyPassword()) {
+ fprintf(stderr, "TestEmptyPassword failed\n");
+ return 1;
+ }
+
+ if (!TestEmptySalt()) {
+ fprintf(stderr, "TestEmptySalt failed\n");
+ return 1;
+ }
+
+ if (!TestRFC6070Vectors()) {
+ fprintf(stderr, "TestRFC6070Vectors failed\n");
+ return 1;
+ }
+
+ if (!TestSHA2()) {
+ fprintf(stderr, "TestSHA2 failed\n");
+ return 1;
+ }
+
+ printf("PASS\n");
+ ERR_free_strings();
+ return 0;
+}
diff --git a/src/crypto/evp/sign.c b/src/crypto/evp/sign.c
index 1faf7c6..ced86bd 100644
--- a/src/crypto/evp/sign.c
+++ b/src/crypto/evp/sign.c
@@ -92,9 +92,9 @@ int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig,
EVP_MD_CTX_cleanup(&tmp_ctx);
pkctx = EVP_PKEY_CTX_new(pkey, NULL);
- if (!pkctx || EVP_PKEY_sign_init(pkctx) <= 0 ||
- EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0 ||
- EVP_PKEY_sign(pkctx, sig, &sig_len, m, m_len) <= 0) {
+ if (!pkctx || !EVP_PKEY_sign_init(pkctx) ||
+ !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) ||
+ !EVP_PKEY_sign(pkctx, sig, &sig_len, m, m_len)) {
goto out;
}
*out_sig_len = sig_len;
@@ -138,8 +138,8 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len,
pkctx = EVP_PKEY_CTX_new(pkey, NULL);
if (!pkctx ||
- EVP_PKEY_verify_init(pkctx) <= 0 ||
- EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) {
+ !EVP_PKEY_verify_init(pkctx) ||
+ !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest)) {
goto out;
}
ret = EVP_PKEY_verify(pkctx, sig, sig_len, m, m_len);