Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0cd846f24f | |||
| 74161f485b | |||
| 7d3a24d9db | |||
| 70fee17204 | |||
| 281a8f5ea3 | |||
| db129f3f3f | |||
| 8b601c88fb | |||
| cac93924ab | |||
| 54858b63c1 | |||
| d054e1bc61 | |||
| 1a63507c41 | |||
| f0558c359c | |||
| 8c0a6ebfc2 | |||
| 83b74c6a7a | |||
| 8f88b27d6a | |||
| de196121b0 | |||
| eda849d2e6 | |||
| 5d7c2f8b1d | |||
| d0637e901d | |||
| b9fbf4069e | |||
| fb0c05cac2 | |||
| c655065273 | |||
| 25638f06e3 | |||
| 939d426f6b | |||
| e2abade424 | |||
| 5d74463301 | |||
| 7361ee42cf | |||
| 5fa22ed85e | |||
| b3c5ac51d5 | |||
| 86f86cbdf7 | |||
| 430a742303 | |||
| d1d8eee76b | |||
| 33f8d33af0 | |||
| d206a11d48 | |||
| beaf594f8b | |||
| 991d31bbf1 | |||
| 9dd9d4fc24 | |||
| a3cc7780e7 | |||
| dd86e75b24 | |||
| fd86eaa868 | |||
| cbac9c3a2d | |||
| 5ddc5b14d9 | |||
| 1b8194715e | |||
| c179854243 | |||
| 8afdbf04bd | |||
| 884614c24f | |||
| cd8f3d36fe |
@@ -4,4 +4,8 @@ AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Right
|
||||
# TODO(davidben): The default for Google style is now Regroup, but the default
|
||||
# IncludeCategories does not recognize <openssl/header.h>. We should
|
||||
# reconfigure IncludeCategories to match. For now, keep it at Preserve.
|
||||
IncludeBlocks: Preserve
|
||||
|
||||
|
||||
+14
-3
@@ -471,7 +471,7 @@ elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "amd64")
|
||||
set(ARCH "x86_64")
|
||||
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64")
|
||||
# cmake reports AMD64 on Windows, but we might be building for 32-bit.
|
||||
if(CMAKE_CL_64)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(ARCH "x86_64")
|
||||
else()
|
||||
set(ARCH "x86")
|
||||
@@ -573,10 +573,21 @@ include_directories(third_party/googletest/include)
|
||||
# themselves as dependencies next to the target definition.
|
||||
add_custom_target(all_tests)
|
||||
|
||||
# On Windows, CRYPTO_TEST_DATA is too long to fit in command-line limits.
|
||||
# TODO(davidben): CMake 3.12 has a list(JOIN) command. Use that when we've
|
||||
# updated the minimum version.
|
||||
set(EMBED_TEST_DATA_ARGS "")
|
||||
foreach(arg ${CRYPTO_TEST_DATA})
|
||||
set(EMBED_TEST_DATA_ARGS "${EMBED_TEST_DATA_ARGS}${arg}\n")
|
||||
endforeach()
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/embed_test_data_args.txt"
|
||||
"${EMBED_TEST_DATA_ARGS}")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT crypto_test_data.cc
|
||||
COMMAND ${GO_EXECUTABLE} run util/embed_test_data.go ${CRYPTO_TEST_DATA} >
|
||||
${CMAKE_CURRENT_BINARY_DIR}/crypto_test_data.cc
|
||||
COMMAND ${GO_EXECUTABLE} run util/embed_test_data.go -file-list
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/embed_test_data_args.txt" >
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/crypto_test_data.cc"
|
||||
DEPENDS util/embed_test_data.go ${CRYPTO_TEST_DATA}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
|
||||
@@ -299,6 +299,7 @@ add_library(
|
||||
evp/sign.c
|
||||
ex_data.c
|
||||
hkdf/hkdf.c
|
||||
hpke/hpke.c
|
||||
hrss/hrss.c
|
||||
lhash/lhash.c
|
||||
mem.c
|
||||
@@ -456,7 +457,7 @@ endif()
|
||||
|
||||
SET_TARGET_PROPERTIES(crypto PROPERTIES LINKER_LANGUAGE C)
|
||||
|
||||
if(NOT MSVC AND NOT ANDROID)
|
||||
if(NOT WIN32 AND NOT ANDROID)
|
||||
target_link_libraries(crypto pthread)
|
||||
endif()
|
||||
|
||||
@@ -519,6 +520,7 @@ add_executable(
|
||||
fipsmodule/rand/fork_detect_test.cc
|
||||
fipsmodule/sha/sha_test.cc
|
||||
hkdf/hkdf_test.cc
|
||||
hpke/hpke_test.cc
|
||||
hmac_extra/hmac_test.cc
|
||||
hrss/hrss_test.cc
|
||||
impl_dispatch_test.cc
|
||||
|
||||
@@ -70,7 +70,7 @@ int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
|
||||
return M_ASN1_BIT_STRING_set(x, d, len);
|
||||
}
|
||||
|
||||
int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
|
||||
int i2c_ASN1_BIT_STRING(const ASN1_BIT_STRING *a, unsigned char **pp)
|
||||
{
|
||||
int ret, j, bits, len;
|
||||
unsigned char *p, *d;
|
||||
@@ -233,7 +233,7 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
|
||||
return (1);
|
||||
}
|
||||
|
||||
int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
|
||||
int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n)
|
||||
{
|
||||
int w, v;
|
||||
|
||||
@@ -250,7 +250,7 @@ int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
|
||||
* which is not specified in 'flags', 1 otherwise.
|
||||
* 'len' is the length of 'flags'.
|
||||
*/
|
||||
int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
|
||||
int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a,
|
||||
unsigned char *flags, int flags_len)
|
||||
{
|
||||
int i, ok;
|
||||
|
||||
@@ -108,7 +108,7 @@ int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
|
||||
return (1);
|
||||
}
|
||||
|
||||
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
|
||||
long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a)
|
||||
{
|
||||
int neg = 0, i;
|
||||
|
||||
@@ -147,7 +147,7 @@ long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
|
||||
return r;
|
||||
}
|
||||
|
||||
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
|
||||
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai)
|
||||
{
|
||||
ASN1_ENUMERATED *ret;
|
||||
int len, j;
|
||||
@@ -183,7 +183,7 @@ ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
|
||||
BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn)
|
||||
{
|
||||
BIGNUM *ret;
|
||||
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@ int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
|
||||
* followed by optional zeros isn't padded.
|
||||
*/
|
||||
|
||||
int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
|
||||
int i2c_ASN1_INTEGER(const ASN1_INTEGER *a, unsigned char **pp)
|
||||
{
|
||||
int pad = 0, ret, i, neg;
|
||||
unsigned char *p, *n, pb = 0;
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
|
||||
int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
|
||||
{
|
||||
unsigned char *p, *allocated = NULL;
|
||||
int objsize;
|
||||
@@ -98,12 +98,12 @@ int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
|
||||
return objsize;
|
||||
}
|
||||
|
||||
int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
|
||||
int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a)
|
||||
{
|
||||
return OBJ_obj2txt(buf, buf_len, a, 0);
|
||||
}
|
||||
|
||||
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
|
||||
int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a)
|
||||
{
|
||||
char buf[80], *p = buf;
|
||||
int i;
|
||||
|
||||
@@ -100,7 +100,7 @@ ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
|
||||
return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
|
||||
}
|
||||
|
||||
int ASN1_TIME_check(ASN1_TIME *t)
|
||||
int ASN1_TIME_check(const ASN1_TIME *t)
|
||||
{
|
||||
if (t->type == V_ASN1_GENERALIZEDTIME)
|
||||
return ASN1_GENERALIZEDTIME_check(t);
|
||||
@@ -110,7 +110,7 @@ int ASN1_TIME_check(ASN1_TIME *t)
|
||||
}
|
||||
|
||||
/* Convert an ASN1_TIME structure to GeneralizedTime */
|
||||
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
|
||||
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t,
|
||||
ASN1_GENERALIZEDTIME **out)
|
||||
{
|
||||
ASN1_GENERALIZEDTIME *ret = NULL;
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/obj.h>
|
||||
|
||||
int ASN1_TYPE_get(ASN1_TYPE *a)
|
||||
int ASN1_TYPE_get(const ASN1_TYPE *a)
|
||||
{
|
||||
if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
|
||||
return (a->type);
|
||||
|
||||
@@ -430,7 +430,7 @@ void ASN1_STRING_length_set(ASN1_STRING *x, int len)
|
||||
return;
|
||||
}
|
||||
|
||||
int ASN1_STRING_type(ASN1_STRING *x)
|
||||
int ASN1_STRING_type(const ASN1_STRING *x)
|
||||
{
|
||||
return M_ASN1_STRING_type(x);
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ TEST(ASN1Test, SerializeObject) {
|
||||
static const uint8_t kDER[] = {0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
|
||||
0xf7, 0x0d, 0x01, 0x01, 0x01};
|
||||
const ASN1_OBJECT *obj = OBJ_nid2obj(NID_rsaEncryption);
|
||||
TestSerialize(const_cast<ASN1_OBJECT *>(obj), i2d_ASN1_OBJECT, kDER);
|
||||
TestSerialize(obj, i2d_ASN1_OBJECT, kDER);
|
||||
}
|
||||
|
||||
TEST(ASN1Test, SerializeBoolean) {
|
||||
|
||||
@@ -93,7 +93,7 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
|
||||
|
||||
/* Extract an ASN1 object from an ASN1_STRING */
|
||||
|
||||
void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
|
||||
void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it)
|
||||
{
|
||||
const unsigned char *p;
|
||||
void *ret;
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
/* Based on a_int.c: equivalent ENUMERATED functions */
|
||||
|
||||
int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a)
|
||||
int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a)
|
||||
{
|
||||
int i, n = 0;
|
||||
static const char *h = "0123456789ABCDEF";
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@
|
||||
|
||||
#include <openssl/bio.h>
|
||||
|
||||
int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
|
||||
int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a)
|
||||
{
|
||||
int i, n = 0;
|
||||
static const char *h = "0123456789ABCDEF";
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
#include <openssl/bio.h>
|
||||
|
||||
int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
|
||||
int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type)
|
||||
{
|
||||
int i, n = 0;
|
||||
static const char *h = "0123456789ABCDEF";
|
||||
|
||||
@@ -50,12 +50,10 @@
|
||||
|
||||
// expand_message_xmd implements the operation described in section 5.3.1 of
|
||||
// draft-irtf-cfrg-hash-to-curve-07. It returns one on success and zero on
|
||||
// allocation failure or if |out_len| was too large. If |is_draft06| is one, it
|
||||
// implements the operation from draft-irtf-cfrg-hash-to-curve-06 instead.
|
||||
// allocation failure or if |out_len| was too large.
|
||||
static int expand_message_xmd(const EVP_MD *md, uint8_t *out, size_t out_len,
|
||||
const uint8_t *msg, size_t msg_len,
|
||||
const uint8_t *dst, size_t dst_len,
|
||||
int is_draft06) {
|
||||
const uint8_t *dst, size_t dst_len) {
|
||||
int ret = 0;
|
||||
const size_t block_size = EVP_MD_block_size(md);
|
||||
const size_t md_size = EVP_MD_size(md);
|
||||
@@ -88,9 +86,8 @@ static int expand_message_xmd(const EVP_MD *md, uint8_t *out, size_t out_len,
|
||||
!EVP_DigestUpdate(&ctx, kZeros, block_size) ||
|
||||
!EVP_DigestUpdate(&ctx, msg, msg_len) ||
|
||||
!EVP_DigestUpdate(&ctx, l_i_b_str_zero, sizeof(l_i_b_str_zero)) ||
|
||||
(is_draft06 && !EVP_DigestUpdate(&ctx, &dst_len_u8, 1)) ||
|
||||
!EVP_DigestUpdate(&ctx, dst, dst_len) ||
|
||||
(!is_draft06 && !EVP_DigestUpdate(&ctx, &dst_len_u8, 1)) ||
|
||||
!EVP_DigestUpdate(&ctx, &dst_len_u8, 1) ||
|
||||
!EVP_DigestFinal_ex(&ctx, b_0, NULL)) {
|
||||
goto err;
|
||||
}
|
||||
@@ -114,9 +111,8 @@ static int expand_message_xmd(const EVP_MD *md, uint8_t *out, size_t out_len,
|
||||
if (!EVP_DigestInit_ex(&ctx, md, NULL) ||
|
||||
!EVP_DigestUpdate(&ctx, b_i, md_size) ||
|
||||
!EVP_DigestUpdate(&ctx, &i, 1) ||
|
||||
(is_draft06 && !EVP_DigestUpdate(&ctx, &dst_len_u8, 1)) ||
|
||||
!EVP_DigestUpdate(&ctx, dst, dst_len) ||
|
||||
(!is_draft06 && !EVP_DigestUpdate(&ctx, &dst_len_u8, 1)) ||
|
||||
!EVP_DigestUpdate(&ctx, &dst_len_u8, 1) ||
|
||||
!EVP_DigestFinal_ex(&ctx, b_i, NULL)) {
|
||||
goto err;
|
||||
}
|
||||
@@ -175,12 +171,11 @@ static void big_endian_to_words(BN_ULONG *out, size_t num_words,
|
||||
static int hash_to_field2(const EC_GROUP *group, const EVP_MD *md,
|
||||
EC_FELEM *out1, EC_FELEM *out2, const uint8_t *dst,
|
||||
size_t dst_len, unsigned k, const uint8_t *msg,
|
||||
size_t msg_len, int is_draft06) {
|
||||
size_t msg_len) {
|
||||
size_t L;
|
||||
uint8_t buf[4 * EC_MAX_BYTES];
|
||||
if (!num_bytes_to_derive(&L, &group->field, k) ||
|
||||
!expand_message_xmd(md, buf, 2 * L, msg, msg_len, dst, dst_len,
|
||||
is_draft06)) {
|
||||
!expand_message_xmd(md, buf, 2 * L, msg, msg_len, dst, dst_len)) {
|
||||
return 0;
|
||||
}
|
||||
BN_ULONG words[2 * EC_MAX_WORDS];
|
||||
@@ -196,12 +191,11 @@ static int hash_to_field2(const EC_GROUP *group, const EVP_MD *md,
|
||||
// group order rather than a field element. |k| is the security factor.
|
||||
static int hash_to_scalar(const EC_GROUP *group, const EVP_MD *md,
|
||||
EC_SCALAR *out, const uint8_t *dst, size_t dst_len,
|
||||
unsigned k, const uint8_t *msg, size_t msg_len,
|
||||
int is_draft06) {
|
||||
unsigned k, const uint8_t *msg, size_t msg_len) {
|
||||
size_t L;
|
||||
uint8_t buf[EC_MAX_BYTES * 2];
|
||||
if (!num_bytes_to_derive(&L, &group->order, k) ||
|
||||
!expand_message_xmd(md, buf, L, msg, msg_len, dst, dst_len, is_draft06)) {
|
||||
!expand_message_xmd(md, buf, L, msg, msg_len, dst, dst_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -310,10 +304,9 @@ static int map_to_curve_simple_swu(const EC_GROUP *group, const EC_FELEM *Z,
|
||||
static int hash_to_curve(const EC_GROUP *group, const EVP_MD *md,
|
||||
const EC_FELEM *Z, const EC_FELEM *c2, unsigned k,
|
||||
EC_RAW_POINT *out, const uint8_t *dst, size_t dst_len,
|
||||
const uint8_t *msg, size_t msg_len, int is_draft06) {
|
||||
const uint8_t *msg, size_t msg_len) {
|
||||
EC_FELEM u0, u1;
|
||||
if (!hash_to_field2(group, md, &u0, &u1, dst, dst_len, k, msg, msg_len,
|
||||
is_draft06)) {
|
||||
if (!hash_to_field2(group, md, &u0, &u1, dst, dst_len, k, msg, msg_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -376,7 +369,7 @@ int ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(
|
||||
ec_felem_neg(group, &Z, &Z);
|
||||
|
||||
return hash_to_curve(group, EVP_sha512(), &Z, &c2, /*k=*/192, out, dst,
|
||||
dst_len, msg, msg_len, /*is_draft06=*/0);
|
||||
dst_len, msg, msg_len);
|
||||
}
|
||||
|
||||
int ec_hash_to_scalar_p384_xmd_sha512_draft07(
|
||||
@@ -388,38 +381,5 @@ int ec_hash_to_scalar_p384_xmd_sha512_draft07(
|
||||
}
|
||||
|
||||
return hash_to_scalar(group, EVP_sha512(), out, dst, dst_len, /*k=*/192, msg,
|
||||
msg_len, /*is_draft06=*/0);
|
||||
}
|
||||
|
||||
int ec_hash_to_curve_p521_xmd_sha512_sswu_draft06(
|
||||
const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst,
|
||||
size_t dst_len, const uint8_t *msg, size_t msg_len) {
|
||||
// See section 8.3 of draft-irtf-cfrg-hash-to-curve-06.
|
||||
if (EC_GROUP_get_curve_name(group) != NID_secp521r1) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Z = -4, c2 = 8.
|
||||
EC_FELEM Z, c2;
|
||||
if (!felem_from_u8(group, &Z, 4) ||
|
||||
!felem_from_u8(group, &c2, 8)) {
|
||||
return 0;
|
||||
}
|
||||
ec_felem_neg(group, &Z, &Z);
|
||||
|
||||
return hash_to_curve(group, EVP_sha512(), &Z, &c2, /*k=*/256, out, dst,
|
||||
dst_len, msg, msg_len, /*is_draft06=*/1);
|
||||
}
|
||||
|
||||
int ec_hash_to_scalar_p521_xmd_sha512_draft06(
|
||||
const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len,
|
||||
const uint8_t *msg, size_t msg_len) {
|
||||
if (EC_GROUP_get_curve_name(group) != NID_secp521r1) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hash_to_scalar(group, EVP_sha512(), out, dst, dst_len, /*k=*/256, msg,
|
||||
msg_len, /*is_draft06=*/1);
|
||||
msg_len);
|
||||
}
|
||||
|
||||
@@ -48,28 +48,6 @@ OPENSSL_EXPORT int ec_hash_to_scalar_p384_xmd_sha512_draft07(
|
||||
const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len,
|
||||
const uint8_t *msg, size_t msg_len);
|
||||
|
||||
// ec_hash_to_curve_p521_xmd_sha512_sswu_draft06 hashes |msg| to a point on
|
||||
// |group| and writes the result to |out|, implementing the
|
||||
// P521_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-06. It
|
||||
// returns one on success and zero on error.
|
||||
//
|
||||
// This function implements an older version of the draft and should not be used
|
||||
// in new code.
|
||||
OPENSSL_EXPORT int ec_hash_to_curve_p521_xmd_sha512_sswu_draft06(
|
||||
const EC_GROUP *group, EC_RAW_POINT *out, const uint8_t *dst,
|
||||
size_t dst_len, const uint8_t *msg, size_t msg_len);
|
||||
|
||||
// ec_hash_to_scalar_p521_xmd_sha512_draft06 hashes |msg| to a scalar on |group|
|
||||
// and writes the result to |out|, using the hash_to_field operation from the
|
||||
// P521_XMD:SHA-512_SSWU_RO_ suite from draft-irtf-cfrg-hash-to-curve-06, but
|
||||
// generating a value modulo the group order rather than a field element.
|
||||
//
|
||||
// This function implements an older version of the draft and should not be used
|
||||
// in new code.
|
||||
OPENSSL_EXPORT int ec_hash_to_scalar_p521_xmd_sha512_draft06(
|
||||
const EC_GROUP *group, EC_SCALAR *out, const uint8_t *dst, size_t dst_len,
|
||||
const uint8_t *msg, size_t msg_len);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern C
|
||||
|
||||
@@ -86,6 +86,7 @@ SSL,160,INVALID_SSL_SESSION
|
||||
SSL,161,INVALID_TICKET_KEYS_LENGTH
|
||||
SSL,302,KEY_USAGE_BIT_INCORRECT
|
||||
SSL,162,LENGTH_MISMATCH
|
||||
SSL,307,MISSING_ALPN
|
||||
SSL,164,MISSING_EXTENSION
|
||||
SSL,258,MISSING_KEY_SHARE
|
||||
SSL,165,MISSING_RSA_CERTIFICATE
|
||||
@@ -174,6 +175,10 @@ SSL,290,SSL_SESSION_ID_TOO_LONG
|
||||
SSL,276,TICKET_ENCRYPTION_FAILED
|
||||
SSL,297,TLS13_DOWNGRADE
|
||||
SSL,1049,TLSV1_ALERT_ACCESS_DENIED
|
||||
SSL,1114,TLSV1_ALERT_BAD_CERTIFICATE_HASH_VALUE
|
||||
SSL,1113,TLSV1_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE
|
||||
SSL,1116,TLSV1_ALERT_CERTIFICATE_REQUIRED
|
||||
SSL,1111,TLSV1_ALERT_CERTIFICATE_UNOBTAINABLE
|
||||
SSL,1050,TLSV1_ALERT_DECODE_ERROR
|
||||
SSL,1021,TLSV1_ALERT_DECRYPTION_FAILED
|
||||
SSL,1051,TLSV1_ALERT_DECRYPT_ERROR
|
||||
@@ -181,18 +186,15 @@ SSL,1060,TLSV1_ALERT_EXPORT_RESTRICTION
|
||||
SSL,1086,TLSV1_ALERT_INAPPROPRIATE_FALLBACK
|
||||
SSL,1071,TLSV1_ALERT_INSUFFICIENT_SECURITY
|
||||
SSL,1080,TLSV1_ALERT_INTERNAL_ERROR
|
||||
SSL,1120,TLSV1_ALERT_NO_APPLICATION_PROTOCOL
|
||||
SSL,1100,TLSV1_ALERT_NO_RENEGOTIATION
|
||||
SSL,1070,TLSV1_ALERT_PROTOCOL_VERSION
|
||||
SSL,1022,TLSV1_ALERT_RECORD_OVERFLOW
|
||||
SSL,1048,TLSV1_ALERT_UNKNOWN_CA
|
||||
SSL,1115,TLSV1_ALERT_UNKNOWN_PSK_IDENTITY
|
||||
SSL,1112,TLSV1_ALERT_UNRECOGNIZED_NAME
|
||||
SSL,1110,TLSV1_ALERT_UNSUPPORTED_EXTENSION
|
||||
SSL,1090,TLSV1_ALERT_USER_CANCELLED
|
||||
SSL,1114,TLSV1_BAD_CERTIFICATE_HASH_VALUE
|
||||
SSL,1113,TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE
|
||||
SSL,1116,TLSV1_CERTIFICATE_REQUIRED
|
||||
SSL,1111,TLSV1_CERTIFICATE_UNOBTAINABLE
|
||||
SSL,1115,TLSV1_UNKNOWN_PSK_IDENTITY
|
||||
SSL,1112,TLSV1_UNRECOGNIZED_NAME
|
||||
SSL,1110,TLSV1_UNSUPPORTED_EXTENSION
|
||||
SSL,217,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST
|
||||
SSL,218,TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
|
||||
SSL,219,TOO_MANY_EMPTY_FRAGMENTS
|
||||
@@ -202,6 +204,7 @@ SSL,300,TOO_MUCH_READ_EARLY_DATA
|
||||
SSL,270,TOO_MUCH_SKIPPED_EARLY_DATA
|
||||
SSL,221,UNABLE_TO_FIND_ECDH_PARAMETERS
|
||||
SSL,293,UNCOMPRESSED_CERT_TOO_LARGE
|
||||
SSL,306,UNEXPECTED_COMPATIBILITY_MODE
|
||||
SSL,222,UNEXPECTED_EXTENSION
|
||||
SSL,279,UNEXPECTED_EXTENSION_ON_EARLY_DATA
|
||||
SSL,223,UNEXPECTED_MESSAGE
|
||||
|
||||
@@ -6,13 +6,16 @@ X509,104,CANT_CHECK_DH_KEY
|
||||
X509,105,CERT_ALREADY_IN_HASH_TABLE
|
||||
X509,106,CRL_ALREADY_DELTA
|
||||
X509,107,CRL_VERIFY_FAILURE
|
||||
X509,138,DELTA_CRL_WITHOUT_CRL_NUMBER
|
||||
X509,108,IDP_MISMATCH
|
||||
X509,109,INVALID_BIT_STRING_BITS_LEFT
|
||||
X509,110,INVALID_DIRECTORY
|
||||
X509,139,INVALID_FIELD_FOR_VERSION
|
||||
X509,111,INVALID_FIELD_NAME
|
||||
X509,136,INVALID_PARAMETER
|
||||
X509,112,INVALID_PSS_PARAMETERS
|
||||
X509,113,INVALID_TRUST
|
||||
X509,140,INVALID_VERSION
|
||||
X509,114,ISSUER_MISMATCH
|
||||
X509,115,KEY_TYPE_MISMATCH
|
||||
X509,116,KEY_VALUES_MISMATCH
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "../bytestring/internal.h"
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
@@ -386,3 +387,145 @@ err:
|
||||
EVP_PKEY_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EVP_PKEY *d2i_PUBKEY(EVP_PKEY **out, const uint8_t **inp, long len) {
|
||||
if (len < 0) {
|
||||
return NULL;
|
||||
}
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, *inp, (size_t)len);
|
||||
EVP_PKEY *ret = EVP_parse_public_key(&cbs);
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (out != NULL) {
|
||||
EVP_PKEY_free(*out);
|
||||
*out = ret;
|
||||
}
|
||||
*inp = CBS_data(&cbs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int i2d_PUBKEY(const EVP_PKEY *pkey, uint8_t **outp) {
|
||||
CBB cbb;
|
||||
if (!CBB_init(&cbb, 128) ||
|
||||
!EVP_marshal_public_key(&cbb, pkey)) {
|
||||
CBB_cleanup(&cbb);
|
||||
return -1;
|
||||
}
|
||||
return CBB_finish_i2d(&cbb, outp);
|
||||
}
|
||||
|
||||
RSA *d2i_RSA_PUBKEY(RSA **out, const uint8_t **inp, long len) {
|
||||
if (len < 0) {
|
||||
return NULL;
|
||||
}
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, *inp, (size_t)len);
|
||||
EVP_PKEY *pkey = EVP_parse_public_key(&cbs);
|
||||
if (pkey == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
RSA *rsa = EVP_PKEY_get1_RSA(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
if (rsa == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (out != NULL) {
|
||||
RSA_free(*out);
|
||||
*out = rsa;
|
||||
}
|
||||
*inp = CBS_data(&cbs);
|
||||
return rsa;
|
||||
}
|
||||
|
||||
int i2d_RSA_PUBKEY(const RSA *rsa, uint8_t **outp) {
|
||||
int ret = -1;
|
||||
EVP_PKEY *pkey = EVP_PKEY_new();
|
||||
if (pkey == NULL ||
|
||||
!EVP_PKEY_set1_RSA(pkey, (RSA *)rsa)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = i2d_PUBKEY(pkey, outp);
|
||||
|
||||
err:
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DSA *d2i_DSA_PUBKEY(DSA **out, const uint8_t **inp, long len) {
|
||||
if (len < 0) {
|
||||
return NULL;
|
||||
}
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, *inp, (size_t)len);
|
||||
EVP_PKEY *pkey = EVP_parse_public_key(&cbs);
|
||||
if (pkey == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
DSA *dsa = EVP_PKEY_get1_DSA(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
if (dsa == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (out != NULL) {
|
||||
DSA_free(*out);
|
||||
*out = dsa;
|
||||
}
|
||||
*inp = CBS_data(&cbs);
|
||||
return dsa;
|
||||
}
|
||||
|
||||
int i2d_DSA_PUBKEY(const DSA *dsa, uint8_t **outp) {
|
||||
int ret = -1;
|
||||
EVP_PKEY *pkey = EVP_PKEY_new();
|
||||
if (pkey == NULL ||
|
||||
!EVP_PKEY_set1_DSA(pkey, (DSA *)dsa)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = i2d_PUBKEY(pkey, outp);
|
||||
|
||||
err:
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EC_KEY *d2i_EC_PUBKEY(EC_KEY **out, const uint8_t **inp, long len) {
|
||||
if (len < 0) {
|
||||
return NULL;
|
||||
}
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, *inp, (size_t)len);
|
||||
EVP_PKEY *pkey = EVP_parse_public_key(&cbs);
|
||||
if (pkey == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
if (ec_key == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (out != NULL) {
|
||||
EC_KEY_free(*out);
|
||||
*out = ec_key;
|
||||
}
|
||||
*inp = CBS_data(&cbs);
|
||||
return ec_key;
|
||||
}
|
||||
|
||||
int i2d_EC_PUBKEY(const EC_KEY *ec_key, uint8_t **outp) {
|
||||
int ret = -1;
|
||||
EVP_PKEY *pkey = EVP_PKEY_new();
|
||||
if (pkey == NULL ||
|
||||
!EVP_PKEY_set1_EC_KEY(pkey, (EC_KEY *)ec_key)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = i2d_PUBKEY(pkey, outp);
|
||||
|
||||
err:
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ BoringCrypto has undergone the following validations:
|
||||
|
||||
1. 2017-06-15: certificate [#2964](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/2964), [security policy](/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20170615.docx) (in docx format).
|
||||
1. 2018-07-30: certificate [#3318](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3318), [security policy](/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20180730.docx) (in docx format).
|
||||
1. 2019-08-08: certificate [#3678](https://csrc.nist.gov/Projects/Cryptographic-Module-Validation-Program/Certificate/3678), [security policy](/crypto/fipsmodule/policydocs/BoringCrypto-Security-Policy-20190808.docx) (in docx format).
|
||||
|
||||
## Running CAVP tests
|
||||
|
||||
|
||||
@@ -404,9 +404,19 @@ uint64_t bn_mont_n0(const BIGNUM *n);
|
||||
int bn_mod_exp_base_2_consttime(BIGNUM *r, unsigned p, const BIGNUM *n,
|
||||
BN_CTX *ctx);
|
||||
|
||||
#if defined(OPENSSL_X86_64) && defined(_MSC_VER)
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(OPENSSL_X86_64)
|
||||
#define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high)))
|
||||
#elif defined(OPENSSL_AARCH64)
|
||||
#define BN_UMULT_LOHI(low, high, a, b) \
|
||||
do { \
|
||||
const BN_ULONG _a = (a); \
|
||||
const BN_ULONG _b = (b); \
|
||||
(low) = _a * _b; \
|
||||
(high) = __umulh(_a, _b); \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif // _MSC_VER
|
||||
|
||||
#if !defined(BN_ULLONG) && !defined(BN_UMULT_LOHI)
|
||||
#error "Either BN_ULLONG or BN_UMULT_LOHI must be defined on every platform."
|
||||
|
||||
@@ -1170,74 +1170,6 @@ TEST(ECTest, HashToCurve) {
|
||||
"37f2913224287b9dfb64742851f760eb14ca115ff9",
|
||||
"1510e764f1be968d661b7aaecb26a6d38c98e5205ca150f0ae426d"
|
||||
"2c3983c68e3a9ffb283c6ae4891d891b5705500475"},
|
||||
|
||||
// Note these tests do not match the tests vectors
|
||||
// draft-irtf-cfrg-hash-to-curve-06 due to a
|
||||
// spec issue. See
|
||||
// https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/pull/238 for
|
||||
// corrected test vectors.
|
||||
{&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1,
|
||||
"P521_XMD:SHA-512_SSWU_RO_TESTGEN", "",
|
||||
"00758617b5e40aa8b30fcfd3c7453ad1abeff158de5697d6f1ccb8"
|
||||
"4690aaa8bb6692986200d16206e85e4f39f1d2829fee1a5904a089"
|
||||
"b4fab3b76873429877c58f99",
|
||||
"016edf324d95fcbe4a30f06751f16cdd5d0b49921dd653cefb3ea2"
|
||||
"dc2b5b903e36d9924a65407283588cc6c224ab6d6324c73cdc166c"
|
||||
"e1530b46984b459e966349b3"},
|
||||
{&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1,
|
||||
"P521_XMD:SHA-512_SSWU_RO_TESTGEN", "abc",
|
||||
"00dcec1a83b676247293e96b1672f67aa5d041a4ded49f542a971a"
|
||||
"60603dd39194f4d8e587f640563a9ab57dcc69af638129b220683f"
|
||||
"f03ed9ad8cfdff3833a01452",
|
||||
"01edc4b497be85361a0afc508058792dc7fc6499a4c51fa3475093"
|
||||
"fd9951ea46fe055e1b007a12caf9be1ce3028bd0b4ca4ffa5200f9"
|
||||
"d11e7fc96e068276ad1319c2"},
|
||||
{&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1,
|
||||
"P521_XMD:SHA-512_SSWU_RO_TESTGEN", "abcdef0123456789",
|
||||
"01f58bfb34825d028c392976a09cebee829734f7714c84b8a13580"
|
||||
"afcc2eb4726e18e307476c1fccdc857a3d6767fd2882875ab132b7"
|
||||
"fa7f3f6bae8954384001b1a1",
|
||||
"00ee0d2d0bfb0bdc6215814fe7096a3dfbf020dce4f0645e8e21a9"
|
||||
"0d6a6113a5ca61ae7d8f3b485b04f2eb2b85e34fc7f9f1bf367386"
|
||||
"2e03932b0acc3655e84d480f"},
|
||||
{&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1,
|
||||
"P521_XMD:SHA-512_SSWU_RO_TESTGEN",
|
||||
"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"016d9a90619bb20c49a2a73cc8c6218cd9b3fb13c720fff2e1f8db"
|
||||
"ac92862c7da4faf404faeff6b64f0d9b1c5824cec99b0d0ed02b3f"
|
||||
"acb6275ce553404ea361503e",
|
||||
"007e301e3357fb1d53961c56e53ce2763e44b297062a3eb14b9f8d"
|
||||
"6aadc92162a74f7e254a606275e76ea0ac343b3bc746f99804bacd"
|
||||
"7351a76fce44347c72a6fe9a"},
|
||||
|
||||
// Custom test vector which triggers long DST path.
|
||||
{&ec_hash_to_curve_p521_xmd_sha512_sswu_draft06, NID_secp521r1,
|
||||
"P521_XMD:SHA-512_SSWU_RO_TESTGEN_aaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"abcdef0123456789",
|
||||
"0036b0c8bbec60335ff8b0397c2cb80283b97051cc949c5c190c28"
|
||||
"92b279fafd6c372dcec3e71eab85c48ed440c14498332548ee46d0"
|
||||
"c85442cbdc5b4032e86c3884",
|
||||
"0081e32ca4378ae89b03142361d9c7fbe66acf0351aca3a71eca50"
|
||||
"7a37fb8673b69cb108d079a248aedd74f06949d6623e7f7605ea10"
|
||||
"f6f751ab574c005db7377d7f"},
|
||||
};
|
||||
|
||||
for (const auto &test : kTests) {
|
||||
@@ -1269,8 +1201,6 @@ TEST(ECTest, HashToCurve) {
|
||||
EC_RAW_POINT p;
|
||||
static const uint8_t kDST[] = {0, 1, 2, 3};
|
||||
static const uint8_t kMessage[] = {4, 5, 6, 7};
|
||||
EXPECT_FALSE(ec_hash_to_curve_p521_xmd_sha512_sswu_draft06(
|
||||
p224.get(), &p, kDST, sizeof(kDST), kMessage, sizeof(kMessage)));
|
||||
EXPECT_FALSE(ec_hash_to_curve_p384_xmd_sha512_sswu_draft07(
|
||||
p224.get(), &p, kDST, sizeof(kDST), kMessage, sizeof(kMessage)));
|
||||
}
|
||||
@@ -1308,31 +1238,6 @@ TEST(ECTest, HashToScalar) {
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"750f2fae7d2b2f41ac737d180c1d4363d85a1504798b4976d40921"
|
||||
"1ddb3651c13a5b4daba9975cdfce18336791131915"},
|
||||
{&ec_hash_to_scalar_p521_xmd_sha512_draft06, NID_secp521r1,
|
||||
"P521_XMD:SHA-512_SCALAR_TEST", "",
|
||||
"01a6206c2fc677c11d51807bf46d64a17f92396673074c5cee9299"
|
||||
"4d28eec5445d5ed89799b30b39c964ecf62f39d59e7d43de15d910"
|
||||
"c2c1d69f3ebc01eab241e5dc"},
|
||||
{&ec_hash_to_scalar_p521_xmd_sha512_draft06, NID_secp521r1,
|
||||
"P521_XMD:SHA-512_SCALAR_TEST", "abcdef0123456789",
|
||||
"00af484a5d9389a9912f555234c578d4b1b7c4a6f5009018d133a4"
|
||||
"069172c9f5ce2d853b8643fe7bb50a83427ed3520a7a793c41a455"
|
||||
"a02aa99431434fb6b5b0b26e"},
|
||||
{&ec_hash_to_scalar_p521_xmd_sha512_draft06, NID_secp521r1,
|
||||
"P521_XMD:SHA-512_SCALAR_TEST",
|
||||
"a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"00b2db2ceb64ad055cafc5a0fc92560525d6dcc4975b86bbb79013"
|
||||
"a1c3ab5d412320cb55df8088a658039a70c5657d5aefaaaa81cc5d"
|
||||
"eecdd40c03eb0517fe2e158c"},
|
||||
};
|
||||
|
||||
for (const auto &test : kTests) {
|
||||
@@ -1358,8 +1263,6 @@ TEST(ECTest, HashToScalar) {
|
||||
EC_SCALAR scalar;
|
||||
static const uint8_t kDST[] = {0, 1, 2, 3};
|
||||
static const uint8_t kMessage[] = {4, 5, 6, 7};
|
||||
EXPECT_FALSE(ec_hash_to_scalar_p521_xmd_sha512_draft06(
|
||||
p224.get(), &scalar, kDST, sizeof(kDST), kMessage, sizeof(kMessage)));
|
||||
EXPECT_FALSE(ec_hash_to_scalar_p384_xmd_sha512_draft07(
|
||||
p224.get(), &scalar, kDST, sizeof(kDST), kMessage, sizeof(kMessage)));
|
||||
}
|
||||
|
||||
@@ -703,7 +703,8 @@ void ec_GFp_mont_felem_to_bytes(const EC_GROUP *group, uint8_t *out,
|
||||
int ec_GFp_mont_felem_from_bytes(const EC_GROUP *group, EC_FELEM *out,
|
||||
const uint8_t *in, size_t len);
|
||||
|
||||
void ec_GFp_nistp_recode_scalar_bits(uint8_t *sign, uint8_t *digit, uint8_t in);
|
||||
void ec_GFp_nistp_recode_scalar_bits(crypto_word_t *sign, crypto_word_t *digit,
|
||||
crypto_word_t in);
|
||||
|
||||
const EC_METHOD *EC_GFp_nistp224_method(void);
|
||||
const EC_METHOD *EC_GFp_nistp256_method(void);
|
||||
|
||||
@@ -866,7 +866,7 @@ static void p224_select_point(const uint64_t idx, size_t size,
|
||||
}
|
||||
|
||||
// p224_get_bit returns the |i|th bit in |in|
|
||||
static char p224_get_bit(const p224_felem_bytearray in, size_t i) {
|
||||
static crypto_word_t p224_get_bit(const p224_felem_bytearray in, size_t i) {
|
||||
if (i >= 224) {
|
||||
return 0;
|
||||
}
|
||||
@@ -977,13 +977,13 @@ static void ec_GFp_nistp224_point_mul(const EC_GROUP *group, EC_RAW_POINT *r,
|
||||
|
||||
// Add every 5 doublings.
|
||||
if (i % 5 == 0) {
|
||||
uint64_t bits = p224_get_bit(scalar->bytes, i + 4) << 5;
|
||||
crypto_word_t bits = p224_get_bit(scalar->bytes, i + 4) << 5;
|
||||
bits |= p224_get_bit(scalar->bytes, i + 3) << 4;
|
||||
bits |= p224_get_bit(scalar->bytes, i + 2) << 3;
|
||||
bits |= p224_get_bit(scalar->bytes, i + 1) << 2;
|
||||
bits |= p224_get_bit(scalar->bytes, i) << 1;
|
||||
bits |= p224_get_bit(scalar->bytes, i - 1);
|
||||
uint8_t sign, digit;
|
||||
crypto_word_t sign, digit;
|
||||
ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
|
||||
|
||||
// Select the point to add or subtract.
|
||||
@@ -1022,7 +1022,7 @@ static void ec_GFp_nistp224_point_mul_base(const EC_GROUP *group,
|
||||
}
|
||||
|
||||
// First, look 28 bits upwards.
|
||||
uint64_t bits = p224_get_bit(scalar->bytes, i + 196) << 3;
|
||||
crypto_word_t bits = p224_get_bit(scalar->bytes, i + 196) << 3;
|
||||
bits |= p224_get_bit(scalar->bytes, i + 140) << 2;
|
||||
bits |= p224_get_bit(scalar->bytes, i + 84) << 1;
|
||||
bits |= p224_get_bit(scalar->bytes, i + 28);
|
||||
@@ -1080,14 +1080,15 @@ static void ec_GFp_nistp224_point_mul_public(const EC_GROUP *group,
|
||||
// Add multiples of the generator.
|
||||
if (i <= 27) {
|
||||
// First, look 28 bits upwards.
|
||||
uint64_t bits = p224_get_bit(g_scalar->bytes, i + 196) << 3;
|
||||
crypto_word_t bits = p224_get_bit(g_scalar->bytes, i + 196) << 3;
|
||||
bits |= p224_get_bit(g_scalar->bytes, i + 140) << 2;
|
||||
bits |= p224_get_bit(g_scalar->bytes, i + 84) << 1;
|
||||
bits |= p224_get_bit(g_scalar->bytes, i + 28);
|
||||
|
||||
size_t index = (size_t)bits;
|
||||
p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
|
||||
g_p224_pre_comp[1][bits][0], g_p224_pre_comp[1][bits][1],
|
||||
g_p224_pre_comp[1][bits][2]);
|
||||
g_p224_pre_comp[1][index][0], g_p224_pre_comp[1][index][1],
|
||||
g_p224_pre_comp[1][index][2]);
|
||||
assert(!skip);
|
||||
|
||||
// Second, look at the current position.
|
||||
@@ -1095,20 +1096,21 @@ static void ec_GFp_nistp224_point_mul_public(const EC_GROUP *group,
|
||||
bits |= p224_get_bit(g_scalar->bytes, i + 112) << 2;
|
||||
bits |= p224_get_bit(g_scalar->bytes, i + 56) << 1;
|
||||
bits |= p224_get_bit(g_scalar->bytes, i);
|
||||
index = (size_t)bits;
|
||||
p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
|
||||
g_p224_pre_comp[0][bits][0], g_p224_pre_comp[0][bits][1],
|
||||
g_p224_pre_comp[0][bits][2]);
|
||||
g_p224_pre_comp[0][index][0], g_p224_pre_comp[0][index][1],
|
||||
g_p224_pre_comp[0][index][2]);
|
||||
}
|
||||
|
||||
// Incorporate |p_scalar| every 5 doublings.
|
||||
if (i % 5 == 0) {
|
||||
uint64_t bits = p224_get_bit(p_scalar->bytes, i + 4) << 5;
|
||||
crypto_word_t bits = p224_get_bit(p_scalar->bytes, i + 4) << 5;
|
||||
bits |= p224_get_bit(p_scalar->bytes, i + 3) << 4;
|
||||
bits |= p224_get_bit(p_scalar->bytes, i + 2) << 3;
|
||||
bits |= p224_get_bit(p_scalar->bytes, i + 1) << 2;
|
||||
bits |= p224_get_bit(p_scalar->bytes, i) << 1;
|
||||
bits |= p224_get_bit(p_scalar->bytes, i - 1);
|
||||
uint8_t sign, digit;
|
||||
crypto_word_t sign, digit;
|
||||
ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
|
||||
|
||||
// Select the point to add or subtract.
|
||||
|
||||
@@ -50,8 +50,8 @@ static const BN_ULONG ONE[P256_LIMBS] = {
|
||||
|
||||
// Recode window to a signed digit, see |ec_GFp_nistp_recode_scalar_bits| in
|
||||
// util.c for details
|
||||
static unsigned booth_recode_w5(unsigned in) {
|
||||
unsigned s, d;
|
||||
static crypto_word_t booth_recode_w5(crypto_word_t in) {
|
||||
crypto_word_t s, d;
|
||||
|
||||
s = ~((in >> 5) - 1);
|
||||
d = (1 << 6) - in - 1;
|
||||
@@ -61,8 +61,8 @@ static unsigned booth_recode_w5(unsigned in) {
|
||||
return (d << 1) + (s & 1);
|
||||
}
|
||||
|
||||
static unsigned booth_recode_w7(unsigned in) {
|
||||
unsigned s, d;
|
||||
static crypto_word_t booth_recode_w7(crypto_word_t in) {
|
||||
crypto_word_t s, d;
|
||||
|
||||
s = ~((in >> 7) - 1);
|
||||
d = (1 << 8) - in - 1;
|
||||
@@ -194,8 +194,8 @@ static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
|
||||
assert(p_scalar != NULL);
|
||||
assert(group->field.width == P256_LIMBS);
|
||||
|
||||
static const unsigned kWindowSize = 5;
|
||||
static const unsigned kMask = (1 << (5 /* kWindowSize */ + 1)) - 1;
|
||||
static const size_t kWindowSize = 5;
|
||||
static const crypto_word_t kMask = (1 << (5 /* kWindowSize */ + 1)) - 1;
|
||||
|
||||
// A |P256_POINT| is (3 * 32) = 96 bytes, and the 64-byte alignment should
|
||||
// add no more than 63 bytes of overhead. Thus, |table| should require
|
||||
@@ -232,17 +232,17 @@ static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
|
||||
|
||||
BN_ULONG tmp[P256_LIMBS];
|
||||
alignas(32) P256_POINT h;
|
||||
unsigned index = 255;
|
||||
unsigned wvalue = p_str[(index - 1) / 8];
|
||||
size_t index = 255;
|
||||
crypto_word_t wvalue = p_str[(index - 1) / 8];
|
||||
wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
|
||||
|
||||
ecp_nistz256_select_w5(r, table, booth_recode_w5(wvalue) >> 1);
|
||||
|
||||
while (index >= 5) {
|
||||
if (index != 255) {
|
||||
unsigned off = (index - 1) / 8;
|
||||
size_t off = (index - 1) / 8;
|
||||
|
||||
wvalue = p_str[off] | p_str[off + 1] << 8;
|
||||
wvalue = (crypto_word_t)p_str[off] | (crypto_word_t)p_str[off + 1] << 8;
|
||||
wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
|
||||
|
||||
wvalue = booth_recode_w5(wvalue);
|
||||
@@ -283,21 +283,22 @@ typedef union {
|
||||
P256_POINT_AFFINE a;
|
||||
} p256_point_union_t;
|
||||
|
||||
static unsigned calc_first_wvalue(unsigned *index, const uint8_t p_str[33]) {
|
||||
static const unsigned kWindowSize = 7;
|
||||
static const unsigned kMask = (1 << (7 /* kWindowSize */ + 1)) - 1;
|
||||
static crypto_word_t calc_first_wvalue(size_t *index, const uint8_t p_str[33]) {
|
||||
static const size_t kWindowSize = 7;
|
||||
static const crypto_word_t kMask = (1 << (7 /* kWindowSize */ + 1)) - 1;
|
||||
*index = kWindowSize;
|
||||
|
||||
unsigned wvalue = (p_str[0] << 1) & kMask;
|
||||
crypto_word_t wvalue = (p_str[0] << 1) & kMask;
|
||||
return booth_recode_w7(wvalue);
|
||||
}
|
||||
|
||||
static unsigned calc_wvalue(unsigned *index, const uint8_t p_str[33]) {
|
||||
static const unsigned kWindowSize = 7;
|
||||
static const unsigned kMask = (1 << (7 /* kWindowSize */ + 1)) - 1;
|
||||
static crypto_word_t calc_wvalue(size_t *index, const uint8_t p_str[33]) {
|
||||
static const size_t kWindowSize = 7;
|
||||
static const crypto_word_t kMask = (1 << (7 /* kWindowSize */ + 1)) - 1;
|
||||
|
||||
const unsigned off = (*index - 1) / 8;
|
||||
unsigned wvalue = p_str[off] | p_str[off + 1] << 8;
|
||||
const size_t off = (*index - 1) / 8;
|
||||
crypto_word_t wvalue =
|
||||
(crypto_word_t)p_str[off] | (crypto_word_t)p_str[off + 1] << 8;
|
||||
wvalue = (wvalue >> ((*index - 1) % 8)) & kMask;
|
||||
*index += kWindowSize;
|
||||
|
||||
@@ -325,8 +326,8 @@ static void ecp_nistz256_point_mul_base(const EC_GROUP *group, EC_RAW_POINT *r,
|
||||
p_str[32] = 0;
|
||||
|
||||
// First window
|
||||
unsigned index = 0;
|
||||
unsigned wvalue = calc_first_wvalue(&index, p_str);
|
||||
size_t index = 0;
|
||||
crypto_word_t wvalue = calc_first_wvalue(&index, p_str);
|
||||
|
||||
ecp_nistz256_select_w7(&p.a, ecp_nistz256_precomputed[0], wvalue >> 1);
|
||||
ecp_nistz256_neg(p.p.Z, p.p.Y);
|
||||
@@ -370,8 +371,8 @@ static void ecp_nistz256_points_mul_public(const EC_GROUP *group,
|
||||
p_str[32] = 0;
|
||||
|
||||
// First window
|
||||
unsigned index = 0;
|
||||
unsigned wvalue = calc_first_wvalue(&index, p_str);
|
||||
size_t index = 0;
|
||||
size_t wvalue = calc_first_wvalue(&index, p_str);
|
||||
|
||||
// Convert |p| from affine to Jacobian coordinates. We set Z to zero if |p|
|
||||
// is infinity and |ONE| otherwise. |p| was computed from the table, so it
|
||||
|
||||
+20
-16
@@ -67,7 +67,7 @@ static fiat_p256_limb_t fiat_p256_nz(
|
||||
|
||||
static void fiat_p256_copy(fiat_p256_limb_t out[FIAT_P256_NLIMBS],
|
||||
const fiat_p256_limb_t in1[FIAT_P256_NLIMBS]) {
|
||||
for (int i = 0; i < FIAT_P256_NLIMBS; i++) {
|
||||
for (size_t i = 0; i < FIAT_P256_NLIMBS; i++) {
|
||||
out[i] = in1[i];
|
||||
}
|
||||
}
|
||||
@@ -393,7 +393,7 @@ static void fiat_p256_select_point(const fiat_p256_limb_t idx, size_t size,
|
||||
}
|
||||
|
||||
// fiat_p256_get_bit returns the |i|th bit in |in|
|
||||
static char fiat_p256_get_bit(const uint8_t *in, int i) {
|
||||
static crypto_word_t fiat_p256_get_bit(const uint8_t *in, int i) {
|
||||
if (i < 0 || i >= 256) {
|
||||
return 0;
|
||||
}
|
||||
@@ -498,20 +498,20 @@ static void ec_GFp_nistp256_point_mul(const EC_GROUP *group, EC_RAW_POINT *r,
|
||||
|
||||
// do other additions every 5 doublings
|
||||
if (i % 5 == 0) {
|
||||
uint64_t bits = fiat_p256_get_bit(scalar->bytes, i + 4) << 5;
|
||||
crypto_word_t bits = fiat_p256_get_bit(scalar->bytes, i + 4) << 5;
|
||||
bits |= fiat_p256_get_bit(scalar->bytes, i + 3) << 4;
|
||||
bits |= fiat_p256_get_bit(scalar->bytes, i + 2) << 3;
|
||||
bits |= fiat_p256_get_bit(scalar->bytes, i + 1) << 2;
|
||||
bits |= fiat_p256_get_bit(scalar->bytes, i) << 1;
|
||||
bits |= fiat_p256_get_bit(scalar->bytes, i - 1);
|
||||
uint8_t sign, digit;
|
||||
crypto_word_t sign, digit;
|
||||
ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
|
||||
|
||||
// select the point to add or subtract, in constant time.
|
||||
fiat_p256_select_point(digit, 17, (const fiat_p256_felem(*)[3])p_pre_comp,
|
||||
tmp);
|
||||
fiat_p256_select_point((fiat_p256_limb_t)digit, 17,
|
||||
(const fiat_p256_felem(*)[3])p_pre_comp, tmp);
|
||||
fiat_p256_opp(ftmp, tmp[1]); // (X, -Y, Z) is the negative point.
|
||||
fiat_p256_cmovznz(tmp[1], sign, tmp[1], ftmp);
|
||||
fiat_p256_cmovznz(tmp[1], (fiat_p256_limb_t)sign, tmp[1], ftmp);
|
||||
|
||||
if (!skip) {
|
||||
fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2],
|
||||
@@ -543,12 +543,13 @@ static void ec_GFp_nistp256_point_mul_base(const EC_GROUP *group,
|
||||
}
|
||||
|
||||
// First, look 32 bits upwards.
|
||||
uint64_t bits = fiat_p256_get_bit(scalar->bytes, i + 224) << 3;
|
||||
crypto_word_t bits = fiat_p256_get_bit(scalar->bytes, i + 224) << 3;
|
||||
bits |= fiat_p256_get_bit(scalar->bytes, i + 160) << 2;
|
||||
bits |= fiat_p256_get_bit(scalar->bytes, i + 96) << 1;
|
||||
bits |= fiat_p256_get_bit(scalar->bytes, i + 32);
|
||||
// Select the point to add, in constant time.
|
||||
fiat_p256_select_point_affine(bits, 15, fiat_p256_g_pre_comp[1], tmp);
|
||||
fiat_p256_select_point_affine((fiat_p256_limb_t)bits, 15,
|
||||
fiat_p256_g_pre_comp[1], tmp);
|
||||
|
||||
if (!skip) {
|
||||
fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2],
|
||||
@@ -566,7 +567,8 @@ static void ec_GFp_nistp256_point_mul_base(const EC_GROUP *group,
|
||||
bits |= fiat_p256_get_bit(scalar->bytes, i + 64) << 1;
|
||||
bits |= fiat_p256_get_bit(scalar->bytes, i);
|
||||
// Select the point to add, in constant time.
|
||||
fiat_p256_select_point_affine(bits, 15, fiat_p256_g_pre_comp[0], tmp);
|
||||
fiat_p256_select_point_affine((fiat_p256_limb_t)bits, 15,
|
||||
fiat_p256_g_pre_comp[0], tmp);
|
||||
fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
|
||||
tmp[0], tmp[1], tmp[2]);
|
||||
}
|
||||
@@ -613,14 +615,15 @@ static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group,
|
||||
// constant-time lookup.
|
||||
if (i <= 31) {
|
||||
// First, look 32 bits upwards.
|
||||
uint64_t bits = fiat_p256_get_bit(g_scalar->bytes, i + 224) << 3;
|
||||
crypto_word_t bits = fiat_p256_get_bit(g_scalar->bytes, i + 224) << 3;
|
||||
bits |= fiat_p256_get_bit(g_scalar->bytes, i + 160) << 2;
|
||||
bits |= fiat_p256_get_bit(g_scalar->bytes, i + 96) << 1;
|
||||
bits |= fiat_p256_get_bit(g_scalar->bytes, i + 32);
|
||||
if (bits != 0) {
|
||||
size_t index = (size_t)(bits - 1);
|
||||
fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2],
|
||||
1 /* mixed */, fiat_p256_g_pre_comp[1][bits - 1][0],
|
||||
fiat_p256_g_pre_comp[1][bits - 1][1],
|
||||
1 /* mixed */, fiat_p256_g_pre_comp[1][index][0],
|
||||
fiat_p256_g_pre_comp[1][index][1],
|
||||
fiat_p256_one);
|
||||
skip = 0;
|
||||
}
|
||||
@@ -631,9 +634,10 @@ static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group,
|
||||
bits |= fiat_p256_get_bit(g_scalar->bytes, i + 64) << 1;
|
||||
bits |= fiat_p256_get_bit(g_scalar->bytes, i);
|
||||
if (bits != 0) {
|
||||
size_t index = (size_t)(bits - 1);
|
||||
fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2],
|
||||
1 /* mixed */, fiat_p256_g_pre_comp[0][bits - 1][0],
|
||||
fiat_p256_g_pre_comp[0][bits - 1][1],
|
||||
1 /* mixed */, fiat_p256_g_pre_comp[0][index][0],
|
||||
fiat_p256_g_pre_comp[0][index][1],
|
||||
fiat_p256_one);
|
||||
skip = 0;
|
||||
}
|
||||
@@ -642,7 +646,7 @@ static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group,
|
||||
int digit = p_wNAF[i];
|
||||
if (digit != 0) {
|
||||
assert(digit & 1);
|
||||
int idx = digit < 0 ? (-digit) >> 1 : digit >> 1;
|
||||
size_t idx = (size_t)(digit < 0 ? (-digit) >> 1 : digit >> 1);
|
||||
fiat_p256_felem *y = &p_pre_comp[idx][1], tmp;
|
||||
if (digit < 0) {
|
||||
fiat_p256_opp(tmp, p_pre_comp[idx][1]);
|
||||
|
||||
@@ -108,7 +108,7 @@ static void ec_GFp_mont_batch_get_window(const EC_GROUP *group,
|
||||
if (i > 0) {
|
||||
window |= bn_is_bit_set_words(scalar->words, width, i - 1);
|
||||
}
|
||||
uint8_t sign, digit;
|
||||
crypto_word_t sign, digit;
|
||||
ec_GFp_nistp_recode_scalar_bits(&sign, &digit, window);
|
||||
|
||||
// Select the entry in constant-time.
|
||||
@@ -121,7 +121,7 @@ static void ec_GFp_mont_batch_get_window(const EC_GROUP *group,
|
||||
// Negate if necessary.
|
||||
EC_FELEM neg_Y;
|
||||
ec_felem_neg(group, &neg_Y, &out->Y);
|
||||
BN_ULONG sign_mask = sign;
|
||||
crypto_word_t sign_mask = sign;
|
||||
sign_mask = 0u - sign_mask;
|
||||
ec_felem_select(group, &out->Y, sign_mask, &neg_Y, &out->Y);
|
||||
}
|
||||
|
||||
@@ -240,9 +240,9 @@
|
||||
// P-384: ...01110011; w = 2, 5, 6, 7 are okay
|
||||
// P-256: ...01010001; w = 5, 7 are okay
|
||||
// P-224: ...00111101; w = 3, 4, 5, 6 are okay
|
||||
void ec_GFp_nistp_recode_scalar_bits(uint8_t *sign, uint8_t *digit,
|
||||
uint8_t in) {
|
||||
uint8_t s, d;
|
||||
void ec_GFp_nistp_recode_scalar_bits(crypto_word_t *sign, crypto_word_t *digit,
|
||||
crypto_word_t in) {
|
||||
crypto_word_t s, d;
|
||||
|
||||
s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as
|
||||
* 6-bit value */
|
||||
|
||||
Binary file not shown.
@@ -108,10 +108,7 @@ die "can't locate x86_64-xlate.pl";
|
||||
# versions, but BoringSSL is intended to be used with pre-generated perlasm
|
||||
# output, so this isn't useful anyway.
|
||||
$avx = 2;
|
||||
|
||||
# TODO(davidben): Consider enabling the Intel SHA Extensions code once it's
|
||||
# been tested.
|
||||
$shaext=0; ### set to zero if compiling for 1.0.1
|
||||
$shaext=1; ### set to zero if compiling for 1.0.1
|
||||
|
||||
open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
|
||||
*STDOUT=*OUT;
|
||||
@@ -456,8 +453,8 @@ $code.=<<___ if ($win64);
|
||||
.Lepilogue_shaext:
|
||||
___
|
||||
$code.=<<___;
|
||||
.cfi_endproc
|
||||
ret
|
||||
.cfi_endproc
|
||||
.size sha1_block_data_order_shaext,.-sha1_block_data_order_shaext
|
||||
___
|
||||
}}}
|
||||
|
||||
@@ -0,0 +1,459 @@
|
||||
/* Copyright (c) 2020, 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 <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/aead.h>
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/digest.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hkdf.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
// As of writing, the editor's draft of HPKE has a number of changes on top of
|
||||
// the latest IETF draft (draft-irtf-cfrg-hpke-04). This file implements the
|
||||
// editor's draft as of July 15, 2020.
|
||||
//
|
||||
// TODO(dmcardle): Remove this comment when draft-irtf-cfrg-hpke-05 is
|
||||
// published.
|
||||
|
||||
#define KEM_CONTEXT_LEN (2 * X25519_PUBLIC_VALUE_LEN)
|
||||
|
||||
// HPKE KEM scheme IDs.
|
||||
#define HPKE_DHKEM_X25519_HKDF_SHA256 0x0020
|
||||
|
||||
// This is strlen("HPKE") + 3 * sizeof(uint16_t).
|
||||
#define HPKE_SUITE_ID_LEN 10
|
||||
|
||||
#define HPKE_MODE_BASE 0
|
||||
|
||||
static const char kHpkeRfcId[] = "RFCXXXX ";
|
||||
|
||||
static int add_label_string(CBB *cbb, const char *label) {
|
||||
return CBB_add_bytes(cbb, (const uint8_t *)label, strlen(label));
|
||||
}
|
||||
|
||||
// The suite_id for the KEM is defined as concat("KEM", I2OSP(kem_id, 2)). Note
|
||||
// that the suite_id used outside of the KEM also includes the kdf_id and
|
||||
// aead_id.
|
||||
static const uint8_t kX25519SuiteID[] = {
|
||||
'K', 'E', 'M', HPKE_DHKEM_X25519_HKDF_SHA256 >> 8,
|
||||
HPKE_DHKEM_X25519_HKDF_SHA256 & 0x00ff};
|
||||
|
||||
// The suite_id for non-KEM pieces of HPKE is defined as concat("HPKE",
|
||||
// I2OSP(kem_id, 2), I2OSP(kdf_id, 2), I2OSP(aead_id, 2)).
|
||||
static int hpke_build_suite_id(uint8_t out[HPKE_SUITE_ID_LEN], uint16_t kdf_id,
|
||||
uint16_t aead_id) {
|
||||
CBB cbb;
|
||||
int ret = CBB_init_fixed(&cbb, out, HPKE_SUITE_ID_LEN) &&
|
||||
add_label_string(&cbb, "HPKE") &&
|
||||
CBB_add_u16(&cbb, HPKE_DHKEM_X25519_HKDF_SHA256) &&
|
||||
CBB_add_u16(&cbb, kdf_id) &&
|
||||
CBB_add_u16(&cbb, aead_id);
|
||||
CBB_cleanup(&cbb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hpke_labeled_extract(const EVP_MD *hkdf_md, uint8_t *out_key,
|
||||
size_t *out_len, const uint8_t *salt,
|
||||
size_t salt_len, const uint8_t *suite_id,
|
||||
size_t suite_id_len, const char *label,
|
||||
const uint8_t *ikm, size_t ikm_len) {
|
||||
// labeledIKM = concat("RFCXXXX ", suite_id, label, IKM)
|
||||
CBB labeled_ikm;
|
||||
int ok = CBB_init(&labeled_ikm, 0) &&
|
||||
add_label_string(&labeled_ikm, kHpkeRfcId) &&
|
||||
CBB_add_bytes(&labeled_ikm, suite_id, suite_id_len) &&
|
||||
add_label_string(&labeled_ikm, label) &&
|
||||
CBB_add_bytes(&labeled_ikm, ikm, ikm_len) &&
|
||||
HKDF_extract(out_key, out_len, hkdf_md, CBB_data(&labeled_ikm),
|
||||
CBB_len(&labeled_ikm), salt, salt_len);
|
||||
CBB_cleanup(&labeled_ikm);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int hpke_labeled_expand(const EVP_MD *hkdf_md, uint8_t *out_key,
|
||||
size_t out_len, const uint8_t *prk,
|
||||
size_t prk_len, const uint8_t *suite_id,
|
||||
size_t suite_id_len, const char *label,
|
||||
const uint8_t *info, size_t info_len) {
|
||||
// labeledInfo = concat(I2OSP(L, 2), "RFCXXXX ", suite_id, label, info)
|
||||
CBB labeled_info;
|
||||
int ok = CBB_init(&labeled_info, 0) &&
|
||||
CBB_add_u16(&labeled_info, out_len) &&
|
||||
add_label_string(&labeled_info, kHpkeRfcId) &&
|
||||
CBB_add_bytes(&labeled_info, suite_id, suite_id_len) &&
|
||||
add_label_string(&labeled_info, label) &&
|
||||
CBB_add_bytes(&labeled_info, info, info_len) &&
|
||||
HKDF_expand(out_key, out_len, hkdf_md, prk, prk_len,
|
||||
CBB_data(&labeled_info), CBB_len(&labeled_info));
|
||||
CBB_cleanup(&labeled_info);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int hpke_extract_and_expand(const EVP_MD *hkdf_md, uint8_t *out_key,
|
||||
size_t out_len,
|
||||
const uint8_t dh[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t kem_context[KEM_CONTEXT_LEN]) {
|
||||
uint8_t prk[EVP_MAX_MD_SIZE];
|
||||
size_t prk_len;
|
||||
static const char kEaePrkLabel[] = "eae_prk";
|
||||
if (!hpke_labeled_extract(hkdf_md, prk, &prk_len, NULL, 0, kX25519SuiteID,
|
||||
sizeof(kX25519SuiteID), kEaePrkLabel, dh,
|
||||
X25519_PUBLIC_VALUE_LEN)) {
|
||||
return 0;
|
||||
}
|
||||
const char kPRKExpandLabel[] = "zz";
|
||||
if (!hpke_labeled_expand(hkdf_md, out_key, out_len, prk, prk_len,
|
||||
kX25519SuiteID, sizeof(kX25519SuiteID),
|
||||
kPRKExpandLabel, kem_context, KEM_CONTEXT_LEN)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const EVP_AEAD *hpke_get_aead(uint16_t aead_id) {
|
||||
switch (aead_id) {
|
||||
case EVP_HPKE_AEAD_AES_GCM_128:
|
||||
return EVP_aead_aes_128_gcm();
|
||||
case EVP_HPKE_AEAD_AES_GCM_256:
|
||||
return EVP_aead_aes_256_gcm();
|
||||
case EVP_HPKE_AEAD_CHACHA20POLY1305:
|
||||
return EVP_aead_chacha20_poly1305();
|
||||
}
|
||||
OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const EVP_MD *hpke_get_kdf(uint16_t kdf_id) {
|
||||
switch (kdf_id) {
|
||||
case EVP_HPKE_HKDF_SHA256:
|
||||
return EVP_sha256();
|
||||
case EVP_HPKE_HKDF_SHA384:
|
||||
return EVP_sha384();
|
||||
case EVP_HPKE_HKDF_SHA512:
|
||||
return EVP_sha512();
|
||||
}
|
||||
OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int hpke_key_schedule(EVP_HPKE_CTX *hpke, const uint8_t *zz,
|
||||
size_t zz_len, const uint8_t *info,
|
||||
size_t info_len) {
|
||||
// Attempt to get an EVP_AEAD*.
|
||||
const EVP_AEAD *aead = hpke_get_aead(hpke->aead_id);
|
||||
if (aead == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t suite_id[HPKE_SUITE_ID_LEN];
|
||||
if (!hpke_build_suite_id(suite_id, hpke->kdf_id, hpke->aead_id)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// pskID_hash = LabeledExtract(zero(0), "pskID_hash", pskID)
|
||||
static const char kPskIdHashLabel[] = "pskID_hash";
|
||||
uint8_t psk_id_hash[EVP_MAX_MD_SIZE];
|
||||
size_t psk_id_hash_len;
|
||||
if (!hpke_labeled_extract(hpke->hkdf_md, psk_id_hash, &psk_id_hash_len, NULL,
|
||||
0, suite_id, sizeof(suite_id), kPskIdHashLabel,
|
||||
NULL, 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// info_hash = LabeledExtract(zero(0), "info_hash", info)
|
||||
static const char kInfoHashLabel[] = "info_hash";
|
||||
uint8_t info_hash[EVP_MAX_MD_SIZE];
|
||||
size_t info_hash_len;
|
||||
if (!hpke_labeled_extract(hpke->hkdf_md, info_hash, &info_hash_len, NULL, 0,
|
||||
suite_id, sizeof(suite_id), kInfoHashLabel, info,
|
||||
info_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// key_schedule_context = concat(mode, pskID_hash, info_hash)
|
||||
uint8_t context[sizeof(uint8_t) + 2 * EVP_MAX_MD_SIZE];
|
||||
size_t context_len;
|
||||
CBB context_cbb;
|
||||
if (!CBB_init_fixed(&context_cbb, context, sizeof(context)) ||
|
||||
!CBB_add_u8(&context_cbb, HPKE_MODE_BASE) ||
|
||||
!CBB_add_bytes(&context_cbb, psk_id_hash, psk_id_hash_len) ||
|
||||
!CBB_add_bytes(&context_cbb, info_hash, info_hash_len) ||
|
||||
!CBB_finish(&context_cbb, NULL, &context_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// psk_hash = LabeledExtract(zero(0), "psk_hash", psk)
|
||||
//
|
||||
// For our purposes, the draft's psk parameter is just the default empty PSK.
|
||||
static const char kPskHashLabel[] = "psk_hash";
|
||||
uint8_t psk_hash[EVP_MAX_MD_SIZE];
|
||||
size_t psk_hash_len;
|
||||
if (!hpke_labeled_extract(hpke->hkdf_md, psk_hash, &psk_hash_len, NULL, 0,
|
||||
suite_id, sizeof(suite_id), kPskHashLabel, NULL,
|
||||
0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// secret = LabeledExtract(psk_hash, "secret", zz)
|
||||
static const char kSecretExtractLabel[] = "secret";
|
||||
uint8_t secret[EVP_MAX_MD_SIZE];
|
||||
size_t secret_len;
|
||||
if (!hpke_labeled_extract(hpke->hkdf_md, secret, &secret_len, psk_hash,
|
||||
psk_hash_len, suite_id, sizeof(suite_id),
|
||||
kSecretExtractLabel, zz, zz_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// key = LabeledExpand(secret, "key", key_schedule_context, Nk)
|
||||
static const char kKeyExpandLabel[] = "key";
|
||||
uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
|
||||
const size_t kKeyLen = EVP_AEAD_key_length(aead);
|
||||
if (!hpke_labeled_expand(hpke->hkdf_md, key, kKeyLen, secret, secret_len,
|
||||
suite_id, sizeof(suite_id), kKeyExpandLabel, context,
|
||||
context_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialize the HPKE context's AEAD context, storing a copy of |key|.
|
||||
if (!EVP_AEAD_CTX_init(&hpke->aead_ctx, aead, key, kKeyLen, 0, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// nonce = LabeledExpand(secret, "nonce", key_schedule_context, Nn)
|
||||
static const char kNonceExpandLabel[] = "nonce";
|
||||
if (!hpke_labeled_expand(hpke->hkdf_md, hpke->nonce,
|
||||
EVP_AEAD_nonce_length(aead), secret, secret_len,
|
||||
suite_id, sizeof(suite_id), kNonceExpandLabel,
|
||||
context, context_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// exporter_secret = LabeledExpand(secret, "exp", key_schedule_context, Nh)
|
||||
static const char kExporterSecretExpandLabel[] = "exp";
|
||||
if (!hpke_labeled_expand(hpke->hkdf_md, hpke->exporter_secret,
|
||||
EVP_MD_size(hpke->hkdf_md), secret, secret_len,
|
||||
suite_id, sizeof(suite_id),
|
||||
kExporterSecretExpandLabel, context, context_len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// The number of bytes written to |out_zz| is the size of the KEM's KDF
|
||||
// (currently we only support SHA256).
|
||||
static int hpke_encap(EVP_HPKE_CTX *hpke, uint8_t out_zz[SHA256_DIGEST_LENGTH],
|
||||
const uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN],
|
||||
const uint8_t ephemeral_public[X25519_PUBLIC_VALUE_LEN]) {
|
||||
uint8_t dh[X25519_PUBLIC_VALUE_LEN];
|
||||
if (!X25519(dh, ephemeral_private, public_key_r)) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t kem_context[KEM_CONTEXT_LEN];
|
||||
OPENSSL_memcpy(kem_context, ephemeral_public, X25519_PUBLIC_VALUE_LEN);
|
||||
OPENSSL_memcpy(kem_context + X25519_PUBLIC_VALUE_LEN, public_key_r,
|
||||
X25519_PUBLIC_VALUE_LEN);
|
||||
if (!hpke_extract_and_expand(EVP_sha256(), out_zz, SHA256_DIGEST_LENGTH, dh,
|
||||
kem_context)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int hpke_decap(const EVP_HPKE_CTX *hpke,
|
||||
uint8_t out_zz[SHA256_DIGEST_LENGTH],
|
||||
const uint8_t enc[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t secret_key_r[X25519_PRIVATE_KEY_LEN]) {
|
||||
uint8_t dh[X25519_PUBLIC_VALUE_LEN];
|
||||
if (!X25519(dh, secret_key_r, enc)) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
|
||||
return 0;
|
||||
}
|
||||
uint8_t kem_context[KEM_CONTEXT_LEN];
|
||||
OPENSSL_memcpy(kem_context, enc, X25519_PUBLIC_VALUE_LEN);
|
||||
OPENSSL_memcpy(kem_context + X25519_PUBLIC_VALUE_LEN, public_key_r,
|
||||
X25519_PUBLIC_VALUE_LEN);
|
||||
if (!hpke_extract_and_expand(EVP_sha256(), out_zz, SHA256_DIGEST_LENGTH, dh,
|
||||
kem_context)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void EVP_HPKE_CTX_init(EVP_HPKE_CTX *ctx) {
|
||||
OPENSSL_memset(ctx, 0, sizeof(EVP_HPKE_CTX));
|
||||
EVP_AEAD_CTX_zero(&ctx->aead_ctx);
|
||||
}
|
||||
|
||||
void EVP_HPKE_CTX_cleanup(EVP_HPKE_CTX *ctx) {
|
||||
EVP_AEAD_CTX_cleanup(&ctx->aead_ctx);
|
||||
}
|
||||
|
||||
int EVP_HPKE_CTX_setup_base_s_x25519(
|
||||
EVP_HPKE_CTX *hpke, uint8_t out_enc[X25519_PUBLIC_VALUE_LEN],
|
||||
uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t peer_public_value[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t *info, size_t info_len) {
|
||||
// The GenerateKeyPair() step technically belongs in the KEM's Encap()
|
||||
// function, but we've moved it up a layer to make it easier for tests to
|
||||
// inject an ephemeral keypair.
|
||||
uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN];
|
||||
X25519_keypair(out_enc, ephemeral_private);
|
||||
return EVP_HPKE_CTX_setup_base_s_x25519_for_test(
|
||||
hpke, kdf_id, aead_id, peer_public_value, info, info_len,
|
||||
ephemeral_private, out_enc);
|
||||
}
|
||||
|
||||
int EVP_HPKE_CTX_setup_base_s_x25519_for_test(
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t peer_public_value[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t *info, size_t info_len,
|
||||
const uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN],
|
||||
const uint8_t ephemeral_public[X25519_PUBLIC_VALUE_LEN]) {
|
||||
hpke->is_sender = 1;
|
||||
hpke->kdf_id = kdf_id;
|
||||
hpke->aead_id = aead_id;
|
||||
hpke->hkdf_md = hpke_get_kdf(kdf_id);
|
||||
if (hpke->hkdf_md == NULL) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t zz[SHA256_DIGEST_LENGTH];
|
||||
if (!hpke_encap(hpke, zz, peer_public_value, ephemeral_private,
|
||||
ephemeral_public) ||
|
||||
!hpke_key_schedule(hpke, zz, sizeof(zz), info, info_len)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t enc[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t public_key[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t private_key[X25519_PRIVATE_KEY_LEN], const uint8_t *info,
|
||||
size_t info_len) {
|
||||
hpke->is_sender = 0;
|
||||
hpke->kdf_id = kdf_id;
|
||||
hpke->aead_id = aead_id;
|
||||
hpke->hkdf_md = hpke_get_kdf(kdf_id);
|
||||
if (hpke->hkdf_md == NULL) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t zz[SHA256_DIGEST_LENGTH];
|
||||
if (!hpke_decap(hpke, zz, enc, public_key, private_key) ||
|
||||
!hpke_key_schedule(hpke, zz, sizeof(zz), info, info_len)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void hpke_nonce(const EVP_HPKE_CTX *hpke, uint8_t *out_nonce,
|
||||
size_t nonce_len) {
|
||||
assert(nonce_len >= 8);
|
||||
|
||||
// Write padded big-endian bytes of |hpke->seq| to |out_nonce|.
|
||||
OPENSSL_memset(out_nonce, 0, nonce_len);
|
||||
uint64_t seq_copy = hpke->seq;
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
out_nonce[nonce_len - i - 1] = seq_copy & 0xff;
|
||||
seq_copy >>= 8;
|
||||
}
|
||||
|
||||
// XOR the encoded sequence with the |hpke->nonce|.
|
||||
for (size_t i = 0; i < nonce_len; i++) {
|
||||
out_nonce[i] ^= hpke->nonce[i];
|
||||
}
|
||||
}
|
||||
|
||||
size_t EVP_HPKE_CTX_max_overhead(const EVP_HPKE_CTX *hpke) {
|
||||
assert(hpke->is_sender);
|
||||
return EVP_AEAD_max_overhead(hpke->aead_ctx.aead);
|
||||
}
|
||||
|
||||
int EVP_HPKE_CTX_open(EVP_HPKE_CTX *hpke, uint8_t *out, size_t *out_len,
|
||||
size_t max_out_len, const uint8_t *in, size_t in_len,
|
||||
const uint8_t *ad, size_t ad_len) {
|
||||
if (hpke->is_sender) {
|
||||
OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
if (hpke->seq == UINT64_MAX) {
|
||||
OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
|
||||
const size_t nonce_len = EVP_AEAD_nonce_length(hpke->aead_ctx.aead);
|
||||
hpke_nonce(hpke, nonce, nonce_len);
|
||||
|
||||
if (!EVP_AEAD_CTX_open(&hpke->aead_ctx, out, out_len, max_out_len, nonce,
|
||||
nonce_len, in, in_len, ad, ad_len)) {
|
||||
return 0;
|
||||
}
|
||||
hpke->seq++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_HPKE_CTX_seal(EVP_HPKE_CTX *hpke, uint8_t *out, size_t *out_len,
|
||||
size_t max_out_len, const uint8_t *in, size_t in_len,
|
||||
const uint8_t *ad, size_t ad_len) {
|
||||
if (!hpke->is_sender) {
|
||||
OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
if (hpke->seq == UINT64_MAX) {
|
||||
OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
|
||||
const size_t nonce_len = EVP_AEAD_nonce_length(hpke->aead_ctx.aead);
|
||||
hpke_nonce(hpke, nonce, nonce_len);
|
||||
|
||||
if (!EVP_AEAD_CTX_seal(&hpke->aead_ctx, out, out_len, max_out_len, nonce,
|
||||
nonce_len, in, in_len, ad, ad_len)) {
|
||||
return 0;
|
||||
}
|
||||
hpke->seq++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_HPKE_CTX_export(const EVP_HPKE_CTX *hpke, uint8_t *out,
|
||||
size_t secret_len, const uint8_t *context,
|
||||
size_t context_len) {
|
||||
uint8_t suite_id[HPKE_SUITE_ID_LEN];
|
||||
if (!hpke_build_suite_id(suite_id, hpke->kdf_id, hpke->aead_id)) {
|
||||
return 0;
|
||||
}
|
||||
static const char kExportExpandLabel[] = "sec";
|
||||
if (!hpke_labeled_expand(hpke->hkdf_md, out, secret_len,
|
||||
hpke->exporter_secret, EVP_MD_size(hpke->hkdf_md),
|
||||
suite_id, sizeof(suite_id), kExportExpandLabel,
|
||||
context, context_len)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,382 @@
|
||||
/* Copyright (c) 2020, 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 <cstdint>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <openssl/base.h>
|
||||
#include <openssl/curve25519.h>
|
||||
#include <openssl/digest.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "../test/file_test.h"
|
||||
#include "../test/test_util.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
namespace bssl {
|
||||
namespace {
|
||||
|
||||
// HpkeTestVector corresponds to one array member in the published
|
||||
// test-vectors.json.
|
||||
class HpkeTestVector {
|
||||
public:
|
||||
explicit HpkeTestVector() = default;
|
||||
~HpkeTestVector() = default;
|
||||
|
||||
bool ReadFromFileTest(FileTest *t);
|
||||
|
||||
void Verify() const {
|
||||
// Set up the sender.
|
||||
ScopedEVP_HPKE_CTX sender_ctx;
|
||||
ASSERT_GT(secret_key_e_.size(), 0u);
|
||||
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_setup_base_s_x25519_for_test(
|
||||
sender_ctx.get(), kdf_id_, aead_id_, public_key_r_.data(), info_.data(),
|
||||
info_.size(), secret_key_e_.data(), public_key_e_.data()));
|
||||
|
||||
// Set up the receiver.
|
||||
ScopedEVP_HPKE_CTX receiver_ctx;
|
||||
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
receiver_ctx.get(), kdf_id_, aead_id_, public_key_e_.data(),
|
||||
public_key_r_.data(), secret_key_r_.data(), info_.data(),
|
||||
info_.size()));
|
||||
|
||||
VerifyEncryptions(sender_ctx.get(), receiver_ctx.get());
|
||||
VerifyExports(sender_ctx.get());
|
||||
VerifyExports(receiver_ctx.get());
|
||||
}
|
||||
|
||||
private:
|
||||
void VerifyEncryptions(EVP_HPKE_CTX *sender_ctx,
|
||||
EVP_HPKE_CTX *receiver_ctx) const {
|
||||
for (const Encryption &task : encryptions_) {
|
||||
std::vector<uint8_t> encrypted(task.plaintext.size() +
|
||||
EVP_HPKE_CTX_max_overhead(sender_ctx));
|
||||
size_t encrypted_len;
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_seal(
|
||||
sender_ctx, encrypted.data(), &encrypted_len, encrypted.size(),
|
||||
task.plaintext.data(), task.plaintext.size(), task.aad.data(),
|
||||
task.aad.size()));
|
||||
|
||||
ASSERT_EQ(Bytes(encrypted.data(), encrypted_len), Bytes(task.ciphertext));
|
||||
|
||||
std::vector<uint8_t> decrypted(task.ciphertext.size());
|
||||
size_t decrypted_len;
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_open(
|
||||
receiver_ctx, decrypted.data(), &decrypted_len, decrypted.size(),
|
||||
task.ciphertext.data(), task.ciphertext.size(), task.aad.data(),
|
||||
task.aad.size()));
|
||||
|
||||
ASSERT_EQ(Bytes(decrypted.data(), decrypted_len), Bytes(task.plaintext));
|
||||
}
|
||||
}
|
||||
|
||||
void VerifyExports(EVP_HPKE_CTX *ctx) const {
|
||||
for (const Export &task : exports_) {
|
||||
std::vector<uint8_t> exported_secret(task.exportLength);
|
||||
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_export(
|
||||
ctx, exported_secret.data(), exported_secret.size(),
|
||||
task.exportContext.data(), task.exportContext.size()));
|
||||
ASSERT_EQ(Bytes(exported_secret), Bytes(task.exportValue));
|
||||
}
|
||||
}
|
||||
|
||||
struct Encryption {
|
||||
std::vector<uint8_t> aad;
|
||||
std::vector<uint8_t> ciphertext;
|
||||
std::vector<uint8_t> plaintext;
|
||||
};
|
||||
|
||||
struct Export {
|
||||
std::vector<uint8_t> exportContext;
|
||||
size_t exportLength;
|
||||
std::vector<uint8_t> exportValue;
|
||||
};
|
||||
|
||||
uint16_t kdf_id_;
|
||||
uint16_t aead_id_;
|
||||
std::vector<uint8_t> context_;
|
||||
std::vector<uint8_t> info_;
|
||||
std::vector<uint8_t> public_key_e_;
|
||||
std::vector<uint8_t> secret_key_e_;
|
||||
std::vector<uint8_t> public_key_r_;
|
||||
std::vector<uint8_t> secret_key_r_;
|
||||
std::vector<Encryption> encryptions_;
|
||||
std::vector<Export> exports_;
|
||||
};
|
||||
|
||||
// Match FileTest's naming scheme for duplicated attribute names.
|
||||
std::string BuildAttrName(const std::string &name, int iter) {
|
||||
return iter == 1 ? name : name + "/" + std::to_string(iter);
|
||||
}
|
||||
|
||||
// Parses |s| as an unsigned integer of type T and writes the value to |out|.
|
||||
// Returns true on success. If the integer value exceeds the maximum T value,
|
||||
// returns false.
|
||||
template <typename T>
|
||||
bool ParseIntSafe(T *out, const std::string &s) {
|
||||
T value = 0;
|
||||
for (char c : s) {
|
||||
if (c < '0' || c > '9') {
|
||||
return false;
|
||||
}
|
||||
if (value > (std::numeric_limits<T>::max() - (c - '0')) / 10) {
|
||||
return false;
|
||||
}
|
||||
value = 10 * value + (c - '0');
|
||||
}
|
||||
*out = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Read the |key| attribute from |file_test| and convert it to an integer.
|
||||
template <typename T>
|
||||
bool FileTestReadInt(FileTest *file_test, T *out, const std::string &key) {
|
||||
std::string s;
|
||||
return file_test->GetAttribute(&s, key) && ParseIntSafe(out, s);
|
||||
}
|
||||
|
||||
|
||||
bool HpkeTestVector::ReadFromFileTest(FileTest *t) {
|
||||
if (!FileTestReadInt(t, &kdf_id_, "kdfID") ||
|
||||
!FileTestReadInt(t, &aead_id_, "aeadID") ||
|
||||
!t->GetBytes(&info_, "info") ||
|
||||
!t->GetBytes(&secret_key_r_, "skRm") ||
|
||||
!t->GetBytes(&public_key_r_, "pkRm") ||
|
||||
!t->GetBytes(&secret_key_e_, "skEm") ||
|
||||
!t->GetBytes(&public_key_e_, "pkEm")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 1; t->HasAttribute(BuildAttrName("aad", i)); i++) {
|
||||
Encryption encryption;
|
||||
if (!t->GetBytes(&encryption.aad, BuildAttrName("aad", i)) ||
|
||||
!t->GetBytes(&encryption.ciphertext, BuildAttrName("ciphertext", i)) ||
|
||||
!t->GetBytes(&encryption.plaintext, BuildAttrName("plaintext", i))) {
|
||||
return false;
|
||||
}
|
||||
encryptions_.push_back(std::move(encryption));
|
||||
}
|
||||
|
||||
for (int i = 1; t->HasAttribute(BuildAttrName("exportContext", i)); i++) {
|
||||
Export exp;
|
||||
if (!t->GetBytes(&exp.exportContext, BuildAttrName("exportContext", i)) ||
|
||||
!FileTestReadInt(t, &exp.exportLength,
|
||||
BuildAttrName("exportLength", i)) ||
|
||||
!t->GetBytes(&exp.exportValue, BuildAttrName("exportValue", i))) {
|
||||
return false;
|
||||
}
|
||||
exports_.push_back(std::move(exp));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(HPKETest, VerifyTestVectors) {
|
||||
FileTestGTest("crypto/hpke/hpke_test_vectors.txt", [](FileTest *t) {
|
||||
HpkeTestVector test_vec;
|
||||
EXPECT_TRUE(test_vec.ReadFromFileTest(t));
|
||||
test_vec.Verify();
|
||||
});
|
||||
}
|
||||
|
||||
// The test vectors used fixed sender ephemeral keys, while HPKE itself
|
||||
// generates new keys for each context. Test this codepath by checking we can
|
||||
// decrypt our own messages.
|
||||
TEST(HPKETest, RoundTrip) {
|
||||
uint16_t kdf_ids[] = {EVP_HPKE_HKDF_SHA256, EVP_HPKE_HKDF_SHA384,
|
||||
EVP_HPKE_HKDF_SHA512};
|
||||
uint16_t aead_ids[] = {EVP_HPKE_AEAD_AES_GCM_128, EVP_HPKE_AEAD_AES_GCM_256,
|
||||
EVP_HPKE_AEAD_CHACHA20POLY1305};
|
||||
|
||||
const uint8_t info_a[] = {1, 1, 2, 3, 5, 8};
|
||||
const uint8_t info_b[] = {42, 42, 42};
|
||||
const uint8_t ad_a[] = {1, 2, 4, 8, 16};
|
||||
const uint8_t ad_b[] = {7};
|
||||
Span<const uint8_t> info_values[] = {{nullptr, 0}, info_a, info_b};
|
||||
Span<const uint8_t> ad_values[] = {{nullptr, 0}, ad_a, ad_b};
|
||||
|
||||
// Generate the receiver's keypair.
|
||||
uint8_t secret_key_r[X25519_PRIVATE_KEY_LEN];
|
||||
uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN];
|
||||
X25519_keypair(public_key_r, secret_key_r);
|
||||
|
||||
for (uint16_t kdf_id : kdf_ids) {
|
||||
for (uint16_t aead_id : aead_ids) {
|
||||
for (const Span<const uint8_t> &info : info_values) {
|
||||
for (const Span<const uint8_t> &ad : ad_values) {
|
||||
// Set up the sender.
|
||||
ScopedEVP_HPKE_CTX sender_ctx;
|
||||
uint8_t enc[X25519_PUBLIC_VALUE_LEN];
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_setup_base_s_x25519(
|
||||
sender_ctx.get(), enc, kdf_id, aead_id, public_key_r, info.data(),
|
||||
info.size()));
|
||||
|
||||
// Set up the receiver.
|
||||
ScopedEVP_HPKE_CTX receiver_ctx;
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
receiver_ctx.get(), kdf_id, aead_id, enc, public_key_r,
|
||||
secret_key_r, info.data(), info.size()));
|
||||
|
||||
const char kCleartextPayload[] = "foobar";
|
||||
|
||||
// Have sender encrypt message for the receiver.
|
||||
std::vector<uint8_t> ciphertext(
|
||||
sizeof(kCleartextPayload) +
|
||||
EVP_HPKE_CTX_max_overhead(sender_ctx.get()));
|
||||
size_t ciphertext_len;
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_seal(
|
||||
sender_ctx.get(), ciphertext.data(), &ciphertext_len,
|
||||
ciphertext.size(),
|
||||
reinterpret_cast<const uint8_t *>(kCleartextPayload),
|
||||
sizeof(kCleartextPayload), ad.data(), ad.size()));
|
||||
|
||||
// Have receiver decrypt the message.
|
||||
std::vector<uint8_t> cleartext(ciphertext.size());
|
||||
size_t cleartext_len;
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_open(receiver_ctx.get(), cleartext.data(),
|
||||
&cleartext_len, cleartext.size(),
|
||||
ciphertext.data(), ciphertext_len,
|
||||
ad.data(), ad.size()));
|
||||
|
||||
// Verify that decrypted message matches the original.
|
||||
ASSERT_EQ(Bytes(cleartext.data(), cleartext_len),
|
||||
Bytes(kCleartextPayload, sizeof(kCleartextPayload)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that the DH operations inside Encap() and Decap() both fail when the
|
||||
// public key is on a small-order point in the curve.
|
||||
TEST(HPKETest, X25519EncapSmallOrderPoint) {
|
||||
// Borrowed from X25519Test.SmallOrder.
|
||||
static const uint8_t kSmallOrderPoint[32] = {
|
||||
0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3,
|
||||
0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32,
|
||||
0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8,
|
||||
};
|
||||
|
||||
// Generate a valid keypair for the receiver.
|
||||
uint8_t secret_key_r[X25519_PRIVATE_KEY_LEN];
|
||||
uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN];
|
||||
X25519_keypair(public_key_r, secret_key_r);
|
||||
|
||||
uint16_t kdf_ids[] = {EVP_HPKE_HKDF_SHA256, EVP_HPKE_HKDF_SHA384,
|
||||
EVP_HPKE_HKDF_SHA512};
|
||||
uint16_t aead_ids[] = {EVP_HPKE_AEAD_AES_GCM_128, EVP_HPKE_AEAD_AES_GCM_256,
|
||||
EVP_HPKE_AEAD_CHACHA20POLY1305};
|
||||
|
||||
for (uint16_t kdf_id : kdf_ids) {
|
||||
for (uint16_t aead_id : aead_ids) {
|
||||
// Set up the sender, passing in kSmallOrderPoint as |peer_public_value|.
|
||||
ScopedEVP_HPKE_CTX sender_ctx;
|
||||
uint8_t enc[X25519_PUBLIC_VALUE_LEN];
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_setup_base_s_x25519(
|
||||
sender_ctx.get(), enc, kdf_id, aead_id, kSmallOrderPoint, nullptr,
|
||||
0));
|
||||
|
||||
// Set up the receiver, passing in kSmallOrderPoint as |enc|.
|
||||
ScopedEVP_HPKE_CTX receiver_ctx;
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
receiver_ctx.get(), kdf_id, aead_id, kSmallOrderPoint, public_key_r,
|
||||
secret_key_r, nullptr, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test that Seal() fails when the context has been initialized as a receiver.
|
||||
TEST(HPKETest, ReceiverInvalidSeal) {
|
||||
const uint8_t kMockEnc[X25519_PUBLIC_VALUE_LEN] = {0xff};
|
||||
const char kCleartextPayload[] = "foobar";
|
||||
|
||||
// Generate the receiver's keypair.
|
||||
uint8_t secret_key_r[X25519_PRIVATE_KEY_LEN];
|
||||
uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN];
|
||||
X25519_keypair(public_key_r, secret_key_r);
|
||||
|
||||
// Set up the receiver.
|
||||
ScopedEVP_HPKE_CTX receiver_ctx;
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
receiver_ctx.get(), EVP_HPKE_HKDF_SHA256, EVP_HPKE_AEAD_AES_GCM_128,
|
||||
kMockEnc, public_key_r, secret_key_r, nullptr, 0));
|
||||
|
||||
// Call Seal() on the receiver.
|
||||
size_t ciphertext_len;
|
||||
uint8_t ciphertext[100];
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_seal(
|
||||
receiver_ctx.get(), ciphertext, &ciphertext_len, sizeof(ciphertext),
|
||||
reinterpret_cast<const uint8_t *>(kCleartextPayload),
|
||||
sizeof(kCleartextPayload), nullptr, 0));
|
||||
}
|
||||
|
||||
// Test that Open() fails when the context has been initialized as a sender.
|
||||
TEST(HPKETest, SenderInvalidOpen) {
|
||||
const uint8_t kMockCiphertext[100] = {0xff};
|
||||
const size_t kMockCiphertextLen = 80;
|
||||
|
||||
// Generate the receiver's keypair.
|
||||
uint8_t secret_key_r[X25519_PRIVATE_KEY_LEN];
|
||||
uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN];
|
||||
X25519_keypair(public_key_r, secret_key_r);
|
||||
|
||||
// Set up the sender.
|
||||
ScopedEVP_HPKE_CTX sender_ctx;
|
||||
uint8_t enc[X25519_PUBLIC_VALUE_LEN];
|
||||
ASSERT_TRUE(EVP_HPKE_CTX_setup_base_s_x25519(
|
||||
sender_ctx.get(), enc, EVP_HPKE_HKDF_SHA256, EVP_HPKE_AEAD_AES_GCM_128,
|
||||
public_key_r, nullptr, 0));
|
||||
|
||||
// Call Open() on the sender.
|
||||
uint8_t cleartext[128];
|
||||
size_t cleartext_len;
|
||||
ASSERT_FALSE(EVP_HPKE_CTX_open(sender_ctx.get(), cleartext, &cleartext_len,
|
||||
sizeof(cleartext), kMockCiphertext,
|
||||
kMockCiphertextLen, nullptr, 0));
|
||||
}
|
||||
|
||||
TEST(HPKETest, InternalParseIntSafe) {
|
||||
uint8_t u8 = 0xff;
|
||||
ASSERT_FALSE(ParseIntSafe(&u8, "-1"));
|
||||
|
||||
ASSERT_TRUE(ParseIntSafe(&u8, "0"));
|
||||
ASSERT_EQ(u8, 0);
|
||||
|
||||
ASSERT_TRUE(ParseIntSafe(&u8, "255"));
|
||||
ASSERT_EQ(u8, 255);
|
||||
|
||||
ASSERT_FALSE(ParseIntSafe(&u8, "256"));
|
||||
|
||||
uint16_t u16 = 0xffff;
|
||||
ASSERT_TRUE(ParseIntSafe(&u16, "257"));
|
||||
ASSERT_EQ(u16, 257);
|
||||
|
||||
ASSERT_TRUE(ParseIntSafe(&u16, "65535"));
|
||||
ASSERT_EQ(u16, 65535);
|
||||
|
||||
ASSERT_FALSE(ParseIntSafe(&u16, "65536"));
|
||||
}
|
||||
|
||||
|
||||
} // namespace bssl
|
||||
@@ -0,0 +1,407 @@
|
||||
kdfID = 1
|
||||
aeadID = 1
|
||||
info = 4f6465206f6e2061204772656369616e2055726e
|
||||
skRm = b3e438a60baef3800d7efd1c4c83c67e003c7c2b36b671b3e51d570f5c224cc6
|
||||
skEm = 46baf826b58e5ad2e6277de734fe5c0bc88d49a3d26d937f2f8b0ef0e361adcc
|
||||
pkRm = 1b033b44a9f9fa57fddd7b583a310f3f8e550099d3af284709ca9eab4fa34673
|
||||
pkEm = 7d832f404f70071d69f285292f0758291f966274fdc5fa494bf6f1bbf81c2252
|
||||
# encryptions[0]
|
||||
aad = 436f756e742d30
|
||||
ciphertext = 437ee37ee8210fcda87a7aae7c5e97b0caf37b93e70b916444cd9762fa3aa2fc877bae2fe16dee3924968063bf
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[1]
|
||||
aad = 436f756e742d31
|
||||
ciphertext = 448fdab5b1331bc2daf1c3e4de42da186c1180235cccf69af0062cb22d646e48cdcd8babe828c3367ba1056c2c
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[2]
|
||||
aad = 436f756e742d32
|
||||
ciphertext = 78af7509a1b84eae6f59b1bdccef888421b020a97f1a6be270363e5c45005389418e73235a942f9fd46b37a352
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[3]
|
||||
aad = 436f756e742d33
|
||||
ciphertext = 5152f55bf389fba1eeb972a88b7a7391f1102b2105f78b1a03baad2543b0ac008f7a59ea64ec044d43d7aeebf8
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[4]
|
||||
aad = 436f756e742d34
|
||||
ciphertext = d4939ff18065a54b1e988c72649aa81b1bbdcf9496d150efbe2c03c084f6477653bc03fd58a58a03d4ab78e47b
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[5]
|
||||
aad = 436f756e742d35
|
||||
ciphertext = 771277b0c50eab4b1aa802b019391f52d2e08459ffea6ca84de9ad691414d15ed9f6f091b3a2190d01e364394c
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[6]
|
||||
aad = 436f756e742d36
|
||||
ciphertext = 914144c371d68501260ce1281e9d4b86710a4184f734e0d00dca765c8e2ffbde118ca63019b749717afc99cc6a
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[7]
|
||||
aad = 436f756e742d37
|
||||
ciphertext = 91c6f9894280f4185b9a1f66d11afd94a81884306c73159b9bad702cf568bbcb5424ecb32388fdf1b0523b99ba
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[8]
|
||||
aad = 436f756e742d38
|
||||
ciphertext = 8901bd3602f5fc51b85367695a4f003e0094e86f01a8564434b12ca2ad290d13476772ae87fbbb091b1a755981
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[9]
|
||||
aad = 436f756e742d39
|
||||
ciphertext = e996c46f77eadd23098140d3223c4b890d1a9ed5b8e02941ab5c93fc370ddbf9477edc26b48b3ec6b8067e32d2
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# exports[0]
|
||||
exportContext = 436f6e746578742d30
|
||||
exportLength = 32
|
||||
exportValue = 9bc841c822d823b56312319e28775373eb5ba1259b6c721393f9bf9868f0ba8e
|
||||
# exports[1]
|
||||
exportContext = 436f6e746578742d31
|
||||
exportLength = 32
|
||||
exportValue = dd76d8a3fbfd50a6468c0a332ebd50ac518ca1747ce5014b4d6fb584968246eb
|
||||
# exports[2]
|
||||
exportContext = 436f6e746578742d32
|
||||
exportLength = 32
|
||||
exportValue = 3a70fe6e8409f204bcfada3d8795c59a676de533d2451b4d5e7506ec48529277
|
||||
# exports[3]
|
||||
exportContext = 436f6e746578742d33
|
||||
exportLength = 32
|
||||
exportValue = 1a5df4a86790fbbe9164463d927ba7b7c7f3daea8d1f39576076b00f03b7372e
|
||||
# exports[4]
|
||||
exportContext = 436f6e746578742d34
|
||||
exportLength = 32
|
||||
exportValue = 03d04b52901947dea1d034489cbc07d8cb94aa3365842c5bb1b6ca52969b86ba
|
||||
|
||||
kdfID = 1
|
||||
aeadID = 2
|
||||
info = 4f6465206f6e2061204772656369616e2055726e
|
||||
skRm = da634eee68734edcd50b2b14c73262fa3ed2726cc85d3c328ccdaabbbec9d53d
|
||||
skEm = e28ec716ac495417440ef674ccf438722932da41b5481b8826f4f7947c4d9069
|
||||
pkRm = 1ea4497701b05912be470df9d06ee114b825b9f9feec09f6aa9b2ca6b7be1360
|
||||
pkEm = 1a468c14ca9d0615f9a14b565c0625058f9b56485006dcab10d762e5260d3041
|
||||
# encryptions[0]
|
||||
aad = 436f756e742d30
|
||||
ciphertext = bb9270559e7f209f764aca4e186040a561e6f2a4f34d6edc59163786ccc41231166f40bf6699f45bc11e25163f
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[1]
|
||||
aad = 436f756e742d31
|
||||
ciphertext = d6743a322f18e3fff2d06e3912b3d484c315772bee09929dba1a27e8e93f11fbced8efbf45d422210bb09f52e5
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[2]
|
||||
aad = 436f756e742d32
|
||||
ciphertext = 89964cbd1aedd4398a9e0fcca0ac245d04e6823666ea639be02bb9ad1bb297e9a974ea1c489414a8e5032a3609
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[3]
|
||||
aad = 436f756e742d33
|
||||
ciphertext = bc8f37b1f7b179b6e97ae97dd08674a7124e9af73b6131b3bff3a071027c27a3e8210522130ad7c2ad20afbbec
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[4]
|
||||
aad = 436f756e742d34
|
||||
ciphertext = e2477e3230130508f8ff9a076b3ff0b4d162defd595962f10dceb9caf72ddddfd8739b184c92a7546e1ad93d49
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[5]
|
||||
aad = 436f756e742d35
|
||||
ciphertext = ee5d485f2e6670b65d7a31fb134823016d3f9059b12bfbda706c4e592f862aca43631f94619f7ad2126bbdf771
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[6]
|
||||
aad = 436f756e742d36
|
||||
ciphertext = a7ebc5793d72288bd382222aae883355a5eab73ba5c7271d66328e1825f3b9f0418e1b204933374e4dd55d8316
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[7]
|
||||
aad = 436f756e742d37
|
||||
ciphertext = 2a5bb8b837de5b0bfea4070918c27c9aadea777bc043189a12dd78aacc197aef16ec3f4d90e7889f8962181bfe
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[8]
|
||||
aad = 436f756e742d38
|
||||
ciphertext = 5fbab7888d1df36f9a7f7607dfc67eb2878e87cb4972fb5e0f2dd6570153c5f64a21bd042fa1a07135482e9767
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[9]
|
||||
aad = 436f756e742d39
|
||||
ciphertext = ac94f708e42b900361fabe181d638d03faf663530bdb635944d5fc48425ee2598b311ba6c7b2495ab9cec34338
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# exports[0]
|
||||
exportContext = 436f6e746578742d30
|
||||
exportLength = 32
|
||||
exportValue = 57c5a85e2538d066a529c321a740e0dba3ab413b5d7a74fd5e9c535dc92a9c93
|
||||
# exports[1]
|
||||
exportContext = 436f6e746578742d31
|
||||
exportLength = 32
|
||||
exportValue = adae370a00458fe0815fb39e0c6708a1e32d8a41d299ec6ec3ff0b3aafa5e9ef
|
||||
# exports[2]
|
||||
exportContext = 436f6e746578742d32
|
||||
exportLength = 32
|
||||
exportValue = 68ddde9847cf50fc0c31eb94a5071c119a4f018bbcff323614b4664808e9567b
|
||||
# exports[3]
|
||||
exportContext = 436f6e746578742d33
|
||||
exportLength = 32
|
||||
exportValue = 6d0684b38f5f05aceefeaaa17bf71b39d5379940761bd38cb0499161565394cf
|
||||
# exports[4]
|
||||
exportContext = 436f6e746578742d34
|
||||
exportLength = 32
|
||||
exportValue = c694953e7e6df9c1d74550b5d54b62a316227c5b08c8f1ff51f124d29b3ae2f8
|
||||
|
||||
kdfID = 1
|
||||
aeadID = 3
|
||||
info = 4f6465206f6e2061204772656369616e2055726e
|
||||
skRm = 677b64ff70915fb0404a1905139013a33fcdbc39f3d1914a007984e2413eca48
|
||||
skEm = 22e0948a3fd086e7ec1cb96155499962bc470680db725dd008d39d25f6191bf6
|
||||
pkRm = 02bd698c34ef1c3ec60d5b209135310d52e125038a0ce0bf1e0ee2c8dfc20e55
|
||||
pkEm = de17360c5c7f244cd06ebc73f2808195329ea69ff829410a6450040d50af363f
|
||||
# encryptions[0]
|
||||
aad = 436f756e742d30
|
||||
ciphertext = b706a7523384a553fb1c44d5d3186bb78484947cd17e72f15f1c83152510e49680cac8f057f175187e94f18083
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[1]
|
||||
aad = 436f756e742d31
|
||||
ciphertext = cdc1a9425ceea83e9f1d0a2be77525460cbe259d1a9314eba520c5f5f879376a9ad7f8672ec943de425c6655c8
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[2]
|
||||
aad = 436f756e742d32
|
||||
ciphertext = 5bb2028896d91f156cd6e171d1470361bc07aa804a3ed64163ea67da67bce84e3d2f73b8d75f9a4dcb452b97e6
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[3]
|
||||
aad = 436f756e742d33
|
||||
ciphertext = 220790f4242aa714ad2c44967810cc8c9483e1833d7f9dadd08999abd892aeb3fb1ca54a29c4ea22d1395d85d3
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[4]
|
||||
aad = 436f756e742d34
|
||||
ciphertext = 73973035d480c8299d1773522b738af626a5c834fc6af5ef5f8778fa6a767da89660f4aea7b4241b1f8b5cdebd
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[5]
|
||||
aad = 436f756e742d35
|
||||
ciphertext = 2e35688b0bed657bc213ce0c960e478e2d708700b3b3ff7048bc62130f23a0752ad867167f1d1b709a48ea89c8
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[6]
|
||||
aad = 436f756e742d36
|
||||
ciphertext = 14dd79e4ee9e416dfb954e4f0d73c44757ad375018a802cd0c4a7ba3fe378e5c8cc4cf21e648e6a8645a085cad
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[7]
|
||||
aad = 436f756e742d37
|
||||
ciphertext = a996ed2f2680a15351eeb87643b99b558a59d8c1114a214acc8bf3dbe6b40c4d41e06ce8b1e11e795e37c75143
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[8]
|
||||
aad = 436f756e742d38
|
||||
ciphertext = 8123ec5ffb77c7395bdf2baf9c73cd2b1bbfa0ec79870a1d6260189b559af29a9478c2675c82bd1e19d2e422bb
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[9]
|
||||
aad = 436f756e742d39
|
||||
ciphertext = 55c9731edc92dee7683bbabc425fafa4dd199aaf74569bec1bbf79e082eab9006392ea1b3a2d07622b62bf0bbf
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# exports[0]
|
||||
exportContext = 436f6e746578742d30
|
||||
exportLength = 32
|
||||
exportValue = bed211016a1fcc4328de46fd11d8be1f00a7e2c17979450e760c152fb77bc825
|
||||
# exports[1]
|
||||
exportContext = 436f6e746578742d31
|
||||
exportLength = 32
|
||||
exportValue = f1c29485807379d0deec17a65606307c2723a1653ecb1bb601ed5f703623fec9
|
||||
# exports[2]
|
||||
exportContext = 436f6e746578742d32
|
||||
exportLength = 32
|
||||
exportValue = 477680ef89421fd862866dfe00b70ac8906785c2346db09c8a868b0c23c28e98
|
||||
# exports[3]
|
||||
exportContext = 436f6e746578742d33
|
||||
exportLength = 32
|
||||
exportValue = d0d5e1460ed084ae579eb5408d03d99482d74b5293e7aa19df06acbf16af8fab
|
||||
# exports[4]
|
||||
exportContext = 436f6e746578742d34
|
||||
exportLength = 32
|
||||
exportValue = f5fec947f00eccf828dcd4f1b405a115001cce97f3bc0d6f8c831f1cbebce36f
|
||||
|
||||
kdfID = 3
|
||||
aeadID = 1
|
||||
info = 4f6465206f6e2061204772656369616e2055726e
|
||||
skRm = 2ad8f8d251b97bdb392dcf671af13d6d26041e411faad5c984f68efaaa3b88b6
|
||||
skEm = b841f4832197fc363c965592a97fa762b04683114a9126f56dfff82c49a6f207
|
||||
pkRm = 6421cec0bf7fdead5b4d3f70acbf6f08577fe73961708e31d6df522d4ad6b20e
|
||||
pkEm = 04ecf81b3a34094121586e4d237fcb9df92df22bb7ae2c0c7c187d839c29b953
|
||||
# encryptions[0]
|
||||
aad = 436f756e742d30
|
||||
ciphertext = 9c4a9834cf1d2bfd16c7fe0a19f9f66afaecb805e06c212f08c245f772de9123e1bf41678f2e910a20158a0273
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[1]
|
||||
aad = 436f756e742d31
|
||||
ciphertext = 1bb872e187c72ac6f89db81309d0fe2c57787efc3d076aab394e0218e33955039650da12e3f0241fd52cef41a5
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[2]
|
||||
aad = 436f756e742d32
|
||||
ciphertext = c5a95f473b853e190b5eab703080c9ddf313d7e6751b2af382ad7f8e910c897757d7256801ef83e408795453c9
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[3]
|
||||
aad = 436f756e742d33
|
||||
ciphertext = 1b5a3d36a34781f93f5508dabc74bd3c82a47bd05af7b2729ef254f42d5a068fa86a918c9cbe1db552d2d8d4d9
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[4]
|
||||
aad = 436f756e742d34
|
||||
ciphertext = 46d9196849ad448e03a7603bb0eb2775586463051f2497f39cdd9211d1fd8ff71c97428639b0764f0ffba29f32
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[5]
|
||||
aad = 436f756e742d35
|
||||
ciphertext = 346a0ecb07e20f32174095a32ef87fde07cefa99fbc70d2cda903fdb8128c204037e7c659b40047e66fc416e19
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[6]
|
||||
aad = 436f756e742d36
|
||||
ciphertext = 41331c5365a8354fe9f221f0ebc6344bd86dfffe253da5cfa06d08089a6e0312e9c18ef57509c9faa2d0995650
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[7]
|
||||
aad = 436f756e742d37
|
||||
ciphertext = b2ff99114ab4b8267f005bb6554b766d6f6c8274c2c669a325354cfb27034afaf0f6f7eb56901292ff804e7553
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[8]
|
||||
aad = 436f756e742d38
|
||||
ciphertext = ae653f1d8dc035745b7e3fc2f81e4e6636f0597a9b6f6f1c7d5b0a23c50d76e1dc0a7cf4fa3b3126e12011302c
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[9]
|
||||
aad = 436f756e742d39
|
||||
ciphertext = 0266729d852d16e9af909841bbe2444bccfab0575cd1c84ff6ddbf3259627fd5b73d24f402bb60bfbee1715951
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# exports[0]
|
||||
exportContext = 436f6e746578742d30
|
||||
exportLength = 32
|
||||
exportValue = 3dba6be0ff119e093d6260766375f0f80c461c6592735ff58a1cf8989805192d
|
||||
# exports[1]
|
||||
exportContext = 436f6e746578742d31
|
||||
exportLength = 32
|
||||
exportValue = e43ef15f82fd672484625d6d3d8b1b157a98a20a6f55c4c084d2fd76b63d3be7
|
||||
# exports[2]
|
||||
exportContext = 436f6e746578742d32
|
||||
exportLength = 32
|
||||
exportValue = 237c2e9a25524ca44ff5683b62e2fb366c583fbb72644b7208e7594e9d3221a5
|
||||
# exports[3]
|
||||
exportContext = 436f6e746578742d33
|
||||
exportLength = 32
|
||||
exportValue = b421f68b38b2bb916e0925a21c80d1a8227ec6ad9a1e1539229142486f88c8af
|
||||
# exports[4]
|
||||
exportContext = 436f6e746578742d34
|
||||
exportLength = 32
|
||||
exportValue = 7736ddde377f0bf3da742d7baac698812a267441c3bcf86b72fed0503bfbac0c
|
||||
|
||||
kdfID = 3
|
||||
aeadID = 2
|
||||
info = 4f6465206f6e2061204772656369616e2055726e
|
||||
skRm = 7dddb757b5c12c7c28b4f7a7e3f4d10f5d077e5d410a66997cb4e73b69e824d7
|
||||
skEm = 089af845076a811768c8eaed47322755f47f4907d2610a1629893d6e1143acca
|
||||
pkRm = ffe3129f906112823ec1c619e0025f5a44cd5a93e0807c61c91336aa22222f6e
|
||||
pkEm = 9bf7495a8ed10966c9f285170ce99ee8aa686095cb1f44500324fae45aba7953
|
||||
# encryptions[0]
|
||||
aad = 436f756e742d30
|
||||
ciphertext = b2263e5b1651fae482259475f2d71d5a95e430ea360c88cfe656ef8cef6a97fec94d0bfb996bd794a183269368
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[1]
|
||||
aad = 436f756e742d31
|
||||
ciphertext = b502c5fb389b8c128f58065f6767063132c53a401300679df875a1688f0d05a0b2e3859add4fe82891356690c8
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[2]
|
||||
aad = 436f756e742d32
|
||||
ciphertext = a0afe304ea046340a3c8c8806f227a2ad6d8a48b583bc6a766af0cd0b0231dc3806d597651b5805cd9062e1f87
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[3]
|
||||
aad = 436f756e742d33
|
||||
ciphertext = 75b462e185cd1af728b4853152379f59af8a29af409a206c9d63b02042089d28662eac4d2af800138bcc52cd34
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[4]
|
||||
aad = 436f756e742d34
|
||||
ciphertext = 2d6a758ac9da40a3a1b965152941bf58602f56e12db95636ad5d9c465a1872884e795ec232bd591ea804829458
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[5]
|
||||
aad = 436f756e742d35
|
||||
ciphertext = dd2e30e1c9b30a0130e88e96239ade666961a8de16d79b75d638ede224d662509a17404e7479097c1658921047
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[6]
|
||||
aad = 436f756e742d36
|
||||
ciphertext = bc20bc221ea15f84e41774bc11b684f074d414be09659b147f186891325f7d52b7d19ae57d9fff88cc4ba825a2
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[7]
|
||||
aad = 436f756e742d37
|
||||
ciphertext = 6ef4d0678cf026651f56c53719a678b178105e1a791051076f2567364a536e8aac76bac03178b2276337e12320
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[8]
|
||||
aad = 436f756e742d38
|
||||
ciphertext = 5da431e3723f549ccada9d122ccd127b031c9a221c7bb360e742e7c0f68fc81d012df7aa1c6181980ce793644c
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[9]
|
||||
aad = 436f756e742d39
|
||||
ciphertext = 9ba2c8e0477d370d71b486c3f52a9f9ef99d7e8991eb50b2692d777e552801f0a7f7deb8d0567ca8575b4c2331
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# exports[0]
|
||||
exportContext = 436f6e746578742d30
|
||||
exportLength = 32
|
||||
exportValue = 9fda6d97dafe3768680d87a5e10fe251aa46693329ebdf56f49b3c467b76e9c0
|
||||
# exports[1]
|
||||
exportContext = 436f6e746578742d31
|
||||
exportLength = 32
|
||||
exportValue = 4c9e496f3265a28a73ce85b3143a5ffba3b55ce8025d735e9ed39aebaab80efe
|
||||
# exports[2]
|
||||
exportContext = 436f6e746578742d32
|
||||
exportLength = 32
|
||||
exportValue = 2425dfcdf16879e51f6c6f3c0d0d0f814d132ad575ce416b7485facd34bb42b9
|
||||
# exports[3]
|
||||
exportContext = 436f6e746578742d33
|
||||
exportLength = 32
|
||||
exportValue = 51f1bdf3bf8bce5b10b76c957034ce3630fe7fc1be7c00bcec7e837ceed2f3cd
|
||||
# exports[4]
|
||||
exportContext = 436f6e746578742d34
|
||||
exportLength = 32
|
||||
exportValue = 80ad324b3e7763a7309ce0615fe8bb5723065be5aa7f68a7ca9e3d3a76c0a0f3
|
||||
|
||||
kdfID = 3
|
||||
aeadID = 3
|
||||
info = 4f6465206f6e2061204772656369616e2055726e
|
||||
skRm = 124759e117f6aa5677c747d09a2d82607db2a388a6473647aeb605b66822819c
|
||||
skEm = 70fe54f14893759e23b4c975cfcb8cbc1ae9b8a4d78a48789a5f47324bda5b84
|
||||
pkRm = 0b9c41a605aba4ffa30f336a976cf4f30a1dd5e8fdf0d4da0f745a147e491828
|
||||
pkEm = 147b25161de4080624c11d1cde83d5a571ba17201385ca22302b9509d1101e46
|
||||
# encryptions[0]
|
||||
aad = 436f756e742d30
|
||||
ciphertext = 77f434a667845f41c5bf5e6e6113484d45fbf7fd61cc36a141b920e4bb5b6ad3a61c67033a15dc495e8595ef45
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[1]
|
||||
aad = 436f756e742d31
|
||||
ciphertext = e5f64ec06a92fb2f81ad6203629d981c265aee092b3e20ddc161e163c0a29d1b9fcc7ddb5dede6d34571406f50
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[2]
|
||||
aad = 436f756e742d32
|
||||
ciphertext = 9252583ed8c5258877afa5dac29acb338cf57c702b03d20130b86234b231e3866b1732369cf6c7fdaace68c246
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[3]
|
||||
aad = 436f756e742d33
|
||||
ciphertext = d5c2e0a633d6786a7d919f40c26ee8a1491a4101a441460d51720ff769b86a71ff74fc9601bd8f4c597d95c057
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[4]
|
||||
aad = 436f756e742d34
|
||||
ciphertext = 807165bdd35f448b9b649ce3ec8a9835836ef88dab28c5a77d0f46bac1dd6f543ebd64bbd7840c860c5a2d1ee5
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[5]
|
||||
aad = 436f756e742d35
|
||||
ciphertext = 208e3adb17a694d567a84428ecf76a562d38fbee827e245eb0e96426429c3a32805f9f675b99a28325c11a9d51
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[6]
|
||||
aad = 436f756e742d36
|
||||
ciphertext = f34e3f00d1b731786b5b7ab0e4bf23fd8f3889d6ee75ca9de755d22f8e099ef0d92a6ab4d6e635c788faaac588
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[7]
|
||||
aad = 436f756e742d37
|
||||
ciphertext = fd45de4d582f57bd5228688c0e08553c3e3d6a875bcd1c67e196b94fc6238ddbf69a17186416669b0ee124bddb
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[8]
|
||||
aad = 436f756e742d38
|
||||
ciphertext = 6416f410aa1aecb24c8c17cd9b6eabda1bfee2bd13aa52c5dfc80c482236b99568de15b3543522486dc594dc13
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# encryptions[9]
|
||||
aad = 436f756e742d39
|
||||
ciphertext = 2bc1f3380dc05ce46a004a679dca47cdc46d25b02662274442562e1f03db3860d1abf28027718cb73a6c2c05f8
|
||||
plaintext = 4265617574792069732074727574682c20747275746820626561757479
|
||||
# exports[0]
|
||||
exportContext = 436f6e746578742d30
|
||||
exportLength = 32
|
||||
exportValue = 73ceb7e41223a42a3e6661f15530ae494ecfd2c6a9e809c67243a0910ee75794
|
||||
# exports[1]
|
||||
exportContext = 436f6e746578742d31
|
||||
exportLength = 32
|
||||
exportValue = 9af39f0e6462be9a3efb1fe2eedc6e2d2942c0c9ecae1ee4e8831d675cce6fc4
|
||||
# exports[2]
|
||||
exportContext = 436f6e746578742d32
|
||||
exportLength = 32
|
||||
exportValue = 0ea567aa2da373a71ff88cc6b91abc8b1dd48baaf032f878a5e6d9335f813003
|
||||
# exports[3]
|
||||
exportContext = 436f6e746578742d33
|
||||
exportLength = 32
|
||||
exportValue = ee6ca654a57a66cd0315716d709d4c52f5f41a69249776c13077967c4c418af2
|
||||
# exports[4]
|
||||
exportContext = 436f6e746578742d34
|
||||
exportLength = 32
|
||||
exportValue = 50dfd00952f71e8c1bd51ed6acde15bd558c97581f7dc17fe6e637d61e12df02
|
||||
@@ -0,0 +1,192 @@
|
||||
/* Copyright (c) 2020, 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. */
|
||||
|
||||
#ifndef OPENSSL_HEADER_CRYPTO_HPKE_INTERNAL_H
|
||||
#define OPENSSL_HEADER_CRYPTO_HPKE_INTERNAL_H
|
||||
|
||||
#include <openssl/aead.h>
|
||||
#include <openssl/base.h>
|
||||
#include <openssl/curve25519.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Hybrid Public Key Encryption.
|
||||
//
|
||||
// Hybrid Public Key Encryption (HPKE) enables a sender to encrypt messages to a
|
||||
// receiver with a public key.
|
||||
//
|
||||
// See https://tools.ietf.org/html/draft-irtf-cfrg-hpke-04.
|
||||
|
||||
// EVP_HPKE_AEAD_* are AEAD identifiers.
|
||||
#define EVP_HPKE_AEAD_AES_GCM_128 0x0001
|
||||
#define EVP_HPKE_AEAD_AES_GCM_256 0x0002
|
||||
#define EVP_HPKE_AEAD_CHACHA20POLY1305 0x0003
|
||||
|
||||
// EVP_HPKE_HKDF_* are HKDF identifiers.
|
||||
#define EVP_HPKE_HKDF_SHA256 0x0001
|
||||
#define EVP_HPKE_HKDF_SHA384 0x0002
|
||||
#define EVP_HPKE_HKDF_SHA512 0x0003
|
||||
|
||||
// EVP_HPKE_MAX_OVERHEAD contains the largest value that
|
||||
// |EVP_HPKE_CTX_max_overhead| would ever return for any context.
|
||||
#define EVP_HPKE_MAX_OVERHEAD EVP_AEAD_MAX_OVERHEAD
|
||||
|
||||
|
||||
// Encryption contexts.
|
||||
|
||||
// An |EVP_HPKE_CTX| is an HPKE encryption context.
|
||||
typedef struct evp_hpke_ctx_st {
|
||||
const EVP_MD *hkdf_md;
|
||||
EVP_AEAD_CTX aead_ctx;
|
||||
uint16_t kdf_id;
|
||||
uint16_t aead_id;
|
||||
uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
|
||||
uint8_t exporter_secret[EVP_MAX_MD_SIZE];
|
||||
uint64_t seq;
|
||||
int is_sender;
|
||||
} EVP_HPKE_CTX;
|
||||
|
||||
// EVP_HPKE_CTX_init initializes an already-allocated |EVP_HPKE_CTX|. The caller
|
||||
// should then use one of the |EVP_HPKE_CTX_setup_*| functions.
|
||||
//
|
||||
// It is safe, but not necessary to call |EVP_HPKE_CTX_cleanup| in this state.
|
||||
OPENSSL_EXPORT void EVP_HPKE_CTX_init(EVP_HPKE_CTX *ctx);
|
||||
|
||||
// EVP_HPKE_CTX_cleanup releases memory referenced by |ctx|. |ctx| must have
|
||||
// been initialized with |EVP_HPKE_CTX_init|.
|
||||
OPENSSL_EXPORT void EVP_HPKE_CTX_cleanup(EVP_HPKE_CTX *ctx);
|
||||
|
||||
|
||||
// Setting up HPKE contexts.
|
||||
//
|
||||
// In each of the following functions, |hpke| must have been initialized with
|
||||
// |EVP_HPKE_CTX_init|. |kdf_id| selects the KDF for non-KEM HPKE operations and
|
||||
// must be one of the |EVP_HPKE_HKDF_*| constants. |aead_id| selects the AEAD
|
||||
// for the "open" and "seal" operations and must be one of the |EVP_HPKE_AEAD_*"
|
||||
// constants."
|
||||
//
|
||||
// See https://www.ietf.org/id/draft-irtf-cfrg-hpke-04.html#section-5.1.1.
|
||||
|
||||
// EVP_HPKE_CTX_setup_base_s_x25519 sets up |hpke| as a sender context that can
|
||||
// encrypt for the private key corresponding to |peer_public_value| (the
|
||||
// recipient's public key). It returns one on success, and zero otherwise. Note
|
||||
// that this function may fail if |peer_public_value| is invalid.
|
||||
//
|
||||
// This function writes the encapsulated shared secret to |out_enc|.
|
||||
OPENSSL_EXPORT int EVP_HPKE_CTX_setup_base_s_x25519(
|
||||
EVP_HPKE_CTX *hpke, uint8_t out_enc[X25519_PUBLIC_VALUE_LEN],
|
||||
uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t peer_public_value[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t *info, size_t info_len);
|
||||
|
||||
// EVP_HPKE_CTX_setup_base_s_x25519_for_test behaves like
|
||||
// |EVP_HPKE_CTX_setup_base_s_x25519|, but takes a pre-generated ephemeral
|
||||
// sender key.
|
||||
OPENSSL_EXPORT int EVP_HPKE_CTX_setup_base_s_x25519_for_test(
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t peer_public_value[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t *info, size_t info_len,
|
||||
const uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN],
|
||||
const uint8_t ephemeral_public[X25519_PUBLIC_VALUE_LEN]);
|
||||
|
||||
// EVP_HPKE_CTX_setup_base_r_x25519 sets up |hpke| as a recipient context that
|
||||
// can decrypt messages. |private_key| is the recipient's private key, and |enc|
|
||||
// is the encapsulated shared secret from the sender. Note that this function
|
||||
// may fail if |enc| is invalid.
|
||||
OPENSSL_EXPORT int EVP_HPKE_CTX_setup_base_r_x25519(
|
||||
EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
|
||||
const uint8_t enc[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t public_key[X25519_PUBLIC_VALUE_LEN],
|
||||
const uint8_t private_key[X25519_PRIVATE_KEY_LEN], const uint8_t *info,
|
||||
size_t info_len);
|
||||
|
||||
|
||||
// Using an HPKE context.
|
||||
|
||||
// EVP_HPKE_CTX_open uses the HPKE context |hpke| to authenticate |in_len| bytes
|
||||
// from |in| and |ad_len| bytes from |ad| and to decrypt at most |in_len| bytes
|
||||
// into |out|. It returns one on success, and zero otherwise.
|
||||
//
|
||||
// This operation will fail if the |hpke| context is not set up as a receiver.
|
||||
//
|
||||
// Note that HPKE encryption is stateful and ordered. The sender's first call to
|
||||
// |EVP_HPKE_CTX_seal| must correspond to the recipient's first call to
|
||||
// |EVP_HPKE_CTX_open|, etc.
|
||||
//
|
||||
// At most |in_len| bytes are written to |out|. In order to ensure success,
|
||||
// |max_out_len| should be at least |in_len|. On successful return, |*out_len|
|
||||
// is set to the actual number of bytes written.
|
||||
OPENSSL_EXPORT int EVP_HPKE_CTX_open(EVP_HPKE_CTX *hpke, uint8_t *out,
|
||||
size_t *out_len, size_t max_out_len,
|
||||
const uint8_t *in, size_t in_len,
|
||||
const uint8_t *ad, size_t ad_len);
|
||||
|
||||
// EVP_HPKE_CTX_seal uses the HPKE context |hpke| to encrypt and authenticate
|
||||
// |in_len| bytes of ciphertext |in| and authenticate |ad_len| bytes from |ad|,
|
||||
// writing the result to |out|. It returns one on success and zero otherwise.
|
||||
//
|
||||
// This operation will fail if the |hpke| context is not set up as a sender.
|
||||
//
|
||||
// Note that HPKE encryption is stateful and ordered. The sender's first call to
|
||||
// |EVP_HPKE_CTX_seal| must correspond to the recipient's first call to
|
||||
// |EVP_HPKE_CTX_open|, etc.
|
||||
//
|
||||
// At most, |max_out_len| encrypted bytes are written to |out|. On successful
|
||||
// return, |*out_len| is set to the actual number of bytes written.
|
||||
//
|
||||
// To ensure success, |max_out_len| should be |in_len| plus the result of
|
||||
// |EVP_HPKE_CTX_max_overhead| or |EVP_HPKE_MAX_OVERHEAD|.
|
||||
OPENSSL_EXPORT int EVP_HPKE_CTX_seal(EVP_HPKE_CTX *hpke, uint8_t *out,
|
||||
size_t *out_len, size_t max_out_len,
|
||||
const uint8_t *in, size_t in_len,
|
||||
const uint8_t *ad, size_t ad_len);
|
||||
|
||||
// EVP_HPKE_CTX_export uses the HPKE context |hpke| to export a secret of
|
||||
// |secret_len| bytes into |out|. This function uses |context_len| bytes from
|
||||
// |context| as a context string for the secret. This is necessary to separate
|
||||
// different uses of exported secrets and bind relevant caller-specific context
|
||||
// into the output. It returns one on success and zero otherwise.
|
||||
OPENSSL_EXPORT int EVP_HPKE_CTX_export(const EVP_HPKE_CTX *hpke, uint8_t *out,
|
||||
size_t secret_len,
|
||||
const uint8_t *context,
|
||||
size_t context_len);
|
||||
|
||||
// EVP_HPKE_CTX_max_overhead returns the maximum number of additional bytes
|
||||
// added by sealing data with |EVP_HPKE_CTX_seal|. The |hpke| context must be
|
||||
// set up as a sender.
|
||||
OPENSSL_EXPORT size_t EVP_HPKE_CTX_max_overhead(const EVP_HPKE_CTX *hpke);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern C
|
||||
#endif
|
||||
|
||||
#if !defined(BORINGSSL_NO_CXX)
|
||||
extern "C++" {
|
||||
|
||||
BSSL_NAMESPACE_BEGIN
|
||||
|
||||
using ScopedEVP_HPKE_CTX =
|
||||
internal::StackAllocated<EVP_HPKE_CTX, void, EVP_HPKE_CTX_init,
|
||||
EVP_HPKE_CTX_cleanup>;
|
||||
|
||||
BSSL_NAMESPACE_END
|
||||
|
||||
} // extern C++
|
||||
#endif
|
||||
|
||||
#endif // OPENSSL_HEADER_CRYPTO_HPKE_INTERNAL_H
|
||||
File diff suppressed because one or more lines are too long
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
# Copyright (c) 2020, 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.
|
||||
|
||||
"""This script translates JSON test vectors to BoringSSL's "FileTest" format.
|
||||
|
||||
Usage: translate_test_vectors.py TEST_VECTORS_JSON_FILE
|
||||
|
||||
The TEST_VECTORS_JSON_FILE is expected to come from the HPKE reference
|
||||
implementation at https://github.com/cisco/go-hpke. The output file is
|
||||
hardcoded as "hpke_test_vectors.txt".
|
||||
"""
|
||||
|
||||
import collections
|
||||
import json
|
||||
import sys
|
||||
|
||||
HPKE_MODE_BASE = 0
|
||||
HPKE_DHKEM_X25519_SHA256 = 0x0020
|
||||
|
||||
|
||||
def read_test_vectors_and_generate_code(json_file_in_path, test_file_out_path):
|
||||
"""Translates JSON test vectors into BoringSSL's FileTest language.
|
||||
|
||||
Args:
|
||||
json_file_in_path: Path to the JSON test vectors file.
|
||||
test_file_out_path: Path to output file.
|
||||
"""
|
||||
|
||||
# Load the JSON file into |test_vecs|.
|
||||
with open(json_file_in_path) as file_in:
|
||||
test_vecs = json.load(file_in)
|
||||
|
||||
lines = []
|
||||
for test in test_vecs:
|
||||
# Filter out test cases that we don't use.
|
||||
if (test["mode"] != HPKE_MODE_BASE or
|
||||
test["kemID"] != HPKE_DHKEM_X25519_SHA256):
|
||||
continue
|
||||
|
||||
for key in ("kdfID", "aeadID", "info", "skRm", "skEm", "pkRm", "pkEm"):
|
||||
lines.append("{} = {}".format(key, str(test[key])))
|
||||
|
||||
for i, enc in enumerate(test["encryptions"]):
|
||||
lines.append("# encryptions[{}]".format(i))
|
||||
for key in ("aad", "ciphertext", "plaintext"):
|
||||
lines.append("{} = {}".format(key, str(enc[key])))
|
||||
|
||||
for i, exp in enumerate(test["exports"]):
|
||||
lines.append("# exports[{}]".format(i))
|
||||
for key in ("exportContext", "exportLength", "exportValue"):
|
||||
lines.append("{} = {}".format(key, str(exp[key])))
|
||||
|
||||
lines.append("")
|
||||
|
||||
with open(test_file_out_path, "w") as file_out:
|
||||
file_out.write("\n".join(lines))
|
||||
|
||||
|
||||
def main(argv):
|
||||
if len(argv) != 2:
|
||||
print(__doc__)
|
||||
sys.exit(1)
|
||||
|
||||
read_test_vectors_and_generate_code(argv[1], "hpke_test_vectors.txt")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
||||
@@ -63,6 +63,13 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
struct pkcs8_priv_key_info_st {
|
||||
ASN1_INTEGER *version;
|
||||
X509_ALGOR *pkeyalg;
|
||||
ASN1_OCTET_STRING *pkey;
|
||||
STACK_OF(X509_ATTRIBUTE) *attributes;
|
||||
};
|
||||
|
||||
// pkcs8_pbe_decrypt decrypts |in| using the PBE scheme described by
|
||||
// |algorithm|, which should be a serialized AlgorithmIdentifier structure. On
|
||||
// success, it sets |*out| to a newly-allocated buffer containing the decrypted
|
||||
|
||||
@@ -96,10 +96,8 @@ static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
// Since the structure must still be valid use ASN1_OP_FREE_PRE
|
||||
if (operation == ASN1_OP_FREE_PRE) {
|
||||
PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval;
|
||||
if (key->pkey && key->pkey->type == V_ASN1_OCTET_STRING &&
|
||||
key->pkey->value.octet_string) {
|
||||
OPENSSL_cleanse(key->pkey->value.octet_string->data,
|
||||
key->pkey->value.octet_string->length);
|
||||
if (key->pkey) {
|
||||
OPENSSL_cleanse(key->pkey->data, key->pkey->length);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@@ -108,12 +106,45 @@ static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = {
|
||||
ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR),
|
||||
ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_ANY),
|
||||
ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_OCTET_STRING),
|
||||
ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0)
|
||||
} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
|
||||
|
||||
int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version,
|
||||
int ptype, void *pval, uint8_t *penc, int penclen) {
|
||||
if (version >= 0 &&
|
||||
!ASN1_INTEGER_set(priv->version, version)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (penc != NULL) {
|
||||
ASN1_STRING_set0(priv->pkey, penc, penclen);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, const uint8_t **pk, int *ppklen,
|
||||
X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8) {
|
||||
if (ppkalg) {
|
||||
*ppkalg = p8->pkeyalg->algorithm;
|
||||
}
|
||||
if (pk) {
|
||||
*pk = ASN1_STRING_data(p8->pkey);
|
||||
*ppklen = ASN1_STRING_length(p8->pkey);
|
||||
}
|
||||
if (pa) {
|
||||
*pa = p8->pkeyalg;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) {
|
||||
uint8_t *der = NULL;
|
||||
int der_len = i2d_PKCS8_PRIV_KEY_INFO(p8, &der);
|
||||
|
||||
@@ -77,27 +77,6 @@ OPENSSL_EXPORT void PMBTOKEN_PRETOKEN_free(PMBTOKEN_PRETOKEN *token);
|
||||
|
||||
DEFINE_STACK_OF(PMBTOKEN_PRETOKEN)
|
||||
|
||||
// The following functions implement the corresponding |TRUST_TOKENS_METHOD|
|
||||
// functions for |TRUST_TOKENS_experiment_v0|'s PMBTokens construction which
|
||||
// uses P-521.
|
||||
int pmbtoken_exp0_generate_key(CBB *out_private, CBB *out_public);
|
||||
int pmbtoken_exp0_client_key_from_bytes(PMBTOKEN_CLIENT_KEY *key,
|
||||
const uint8_t *in, size_t len);
|
||||
int pmbtoken_exp0_issuer_key_from_bytes(PMBTOKEN_ISSUER_KEY *key,
|
||||
const uint8_t *in, size_t len);
|
||||
STACK_OF(PMBTOKEN_PRETOKEN) * pmbtoken_exp0_blind(CBB *cbb, size_t count);
|
||||
int pmbtoken_exp0_sign(const PMBTOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
|
||||
size_t num_requested, size_t num_to_issue,
|
||||
uint8_t private_metadata);
|
||||
STACK_OF(TRUST_TOKEN) *
|
||||
pmbtoken_exp0_unblind(const PMBTOKEN_CLIENT_KEY *key,
|
||||
const STACK_OF(PMBTOKEN_PRETOKEN) * pretokens,
|
||||
CBS *cbs, size_t count, uint32_t key_id);
|
||||
int pmbtoken_exp0_read(const PMBTOKEN_ISSUER_KEY *key,
|
||||
uint8_t out_nonce[PMBTOKEN_NONCE_SIZE],
|
||||
uint8_t *out_private_metadata, const uint8_t *token,
|
||||
size_t token_len);
|
||||
|
||||
// The following functions implement the corresponding |TRUST_TOKENS_METHOD|
|
||||
// functions for |TRUST_TOKENS_experiment_v1|'s PMBTokens construction which
|
||||
// uses P-384.
|
||||
@@ -193,14 +172,6 @@ struct trust_token_method_st {
|
||||
uint8_t out_nonce[PMBTOKEN_NONCE_SIZE],
|
||||
uint8_t *out_private_metadata, const uint8_t *token,
|
||||
size_t token_len);
|
||||
|
||||
// use_token_hash determines whether to include the token hash in the SRR and
|
||||
// private metadata encryption.
|
||||
int use_token_hash : 1;
|
||||
|
||||
// batched_proof determines whether PMBToken uses a batched DLEQOR proof when
|
||||
// signing tokens.
|
||||
int batched_proof : 1;
|
||||
};
|
||||
|
||||
// Structure representing a single Trust Token public key with the specified ID.
|
||||
|
||||
+116
-363
@@ -52,9 +52,6 @@ typedef struct {
|
||||
// hash_c implements the H_c operation in PMBTokens. It returns one on success
|
||||
// and zero on error.
|
||||
hash_c_func_t hash_c;
|
||||
// batched_proof determines whether PMBToken uses a batched DLEQOR proof when
|
||||
// signing tokens.
|
||||
int batched_proof : 1;
|
||||
} PMBTOKEN_METHOD;
|
||||
|
||||
static const uint8_t kDefaultAdditionalData[32] = {0};
|
||||
@@ -62,7 +59,7 @@ static const uint8_t kDefaultAdditionalData[32] = {0};
|
||||
static int pmbtoken_init_method(PMBTOKEN_METHOD *method, int curve_nid,
|
||||
const uint8_t *h_bytes, size_t h_len,
|
||||
hash_t_func_t hash_t, hash_s_func_t hash_s,
|
||||
hash_c_func_t hash_c, int batched_proof) {
|
||||
hash_c_func_t hash_c) {
|
||||
method->group = EC_GROUP_new_by_curve_name(curve_nid);
|
||||
if (method->group == NULL) {
|
||||
return 0;
|
||||
@@ -71,7 +68,6 @@ static int pmbtoken_init_method(PMBTOKEN_METHOD *method, int curve_nid,
|
||||
method->hash_t = hash_t;
|
||||
method->hash_s = hash_s;
|
||||
method->hash_c = hash_c;
|
||||
method->batched_proof = batched_proof;
|
||||
|
||||
EC_AFFINE h;
|
||||
if (!ec_point_from_uncompressed(method->group, &h, h_bytes, h_len)) {
|
||||
@@ -724,37 +720,31 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (num_to_issue > ((size_t)-1) / sizeof(EC_RAW_POINT) ||
|
||||
num_to_issue > ((size_t)-1) / sizeof(EC_SCALAR)) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
EC_RAW_POINT *Tps = NULL;
|
||||
EC_RAW_POINT *Sps = NULL;
|
||||
EC_RAW_POINT *Wps = NULL;
|
||||
EC_RAW_POINT *Wsps = NULL;
|
||||
EC_SCALAR *es = NULL;
|
||||
EC_RAW_POINT *Tps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT));
|
||||
EC_RAW_POINT *Sps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT));
|
||||
EC_RAW_POINT *Wps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT));
|
||||
EC_RAW_POINT *Wsps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT));
|
||||
EC_SCALAR *es = OPENSSL_malloc(num_to_issue * sizeof(EC_SCALAR));
|
||||
CBB batch_cbb;
|
||||
CBB_zero(&batch_cbb);
|
||||
if (method->batched_proof) {
|
||||
if (num_to_issue > ((size_t)-1) / sizeof(EC_RAW_POINT) ||
|
||||
num_to_issue > ((size_t)-1) / sizeof(EC_SCALAR)) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
|
||||
goto err;
|
||||
}
|
||||
Tps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT));
|
||||
Sps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT));
|
||||
Wps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT));
|
||||
Wsps = OPENSSL_malloc(num_to_issue * sizeof(EC_RAW_POINT));
|
||||
es = OPENSSL_malloc(num_to_issue * sizeof(EC_SCALAR));
|
||||
if (!Tps ||
|
||||
!Sps ||
|
||||
!Wps ||
|
||||
!Wsps ||
|
||||
!es ||
|
||||
!CBB_init(&batch_cbb, 0) ||
|
||||
!point_to_cbb(&batch_cbb, method->group, &key->pubs) ||
|
||||
!point_to_cbb(&batch_cbb, method->group, &key->pub0) ||
|
||||
!point_to_cbb(&batch_cbb, method->group, &key->pub1)) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!Tps ||
|
||||
!Sps ||
|
||||
!Wps ||
|
||||
!Wsps ||
|
||||
!es ||
|
||||
!CBB_init(&batch_cbb, 0) ||
|
||||
!point_to_cbb(&batch_cbb, method->group, &key->pubs) ||
|
||||
!point_to_cbb(&batch_cbb, method->group, &key->pub0) ||
|
||||
!point_to_cbb(&batch_cbb, method->group, &key->pub1)) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < num_to_issue; i++) {
|
||||
@@ -793,25 +783,17 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!method->batched_proof) {
|
||||
if (!CBB_add_u16_length_prefixed(cbb, &child) ||
|
||||
!dleq_generate(method, &child, key, &Tp, &jacobians[0], &jacobians[1],
|
||||
&jacobians[2], private_metadata)) {
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
if (!point_to_cbb(&batch_cbb, group, &Tp_affine) ||
|
||||
!point_to_cbb(&batch_cbb, group, &affines[0]) ||
|
||||
!point_to_cbb(&batch_cbb, group, &affines[1]) ||
|
||||
!point_to_cbb(&batch_cbb, group, &affines[2])) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
Tps[i] = Tp;
|
||||
Sps[i] = jacobians[0];
|
||||
Wps[i] = jacobians[1];
|
||||
Wsps[i] = jacobians[2];
|
||||
if (!point_to_cbb(&batch_cbb, group, &Tp_affine) ||
|
||||
!point_to_cbb(&batch_cbb, group, &affines[0]) ||
|
||||
!point_to_cbb(&batch_cbb, group, &affines[1]) ||
|
||||
!point_to_cbb(&batch_cbb, group, &affines[2])) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
Tps[i] = Tp;
|
||||
Sps[i] = jacobians[0];
|
||||
Wps[i] = jacobians[1];
|
||||
Wsps[i] = jacobians[2];
|
||||
|
||||
if (!CBB_flush(cbb)) {
|
||||
goto err;
|
||||
@@ -821,36 +803,34 @@ static int pmbtoken_sign(const PMBTOKEN_METHOD *method,
|
||||
// The DLEQ batching construction is described in appendix B of
|
||||
// https://eprint.iacr.org/2020/072/20200324:214215. Note the additional
|
||||
// computations all act on public inputs.
|
||||
if (method->batched_proof) {
|
||||
for (size_t i = 0; i < num_to_issue; i++) {
|
||||
if (!hash_c_batch(method, &es[i], &batch_cbb, i)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
EC_RAW_POINT Tp_batch, Sp_batch, Wp_batch, Wsp_batch;
|
||||
if (!ec_point_mul_scalar_public_batch(group, &Tp_batch,
|
||||
/*g_scalar=*/NULL, Tps, es,
|
||||
num_to_issue) ||
|
||||
!ec_point_mul_scalar_public_batch(group, &Sp_batch,
|
||||
/*g_scalar=*/NULL, Sps, es,
|
||||
num_to_issue) ||
|
||||
!ec_point_mul_scalar_public_batch(group, &Wp_batch,
|
||||
/*g_scalar=*/NULL, Wps, es,
|
||||
num_to_issue) ||
|
||||
!ec_point_mul_scalar_public_batch(group, &Wsp_batch,
|
||||
/*g_scalar=*/NULL, Wsps, es,
|
||||
num_to_issue)) {
|
||||
for (size_t i = 0; i < num_to_issue; i++) {
|
||||
if (!hash_c_batch(method, &es[i], &batch_cbb, i)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
CBB proof;
|
||||
if (!CBB_add_u16_length_prefixed(cbb, &proof) ||
|
||||
!dleq_generate(method, &proof, key, &Tp_batch, &Sp_batch, &Wp_batch,
|
||||
&Wsp_batch, private_metadata) ||
|
||||
!CBB_flush(cbb)) {
|
||||
goto err;
|
||||
}
|
||||
EC_RAW_POINT Tp_batch, Sp_batch, Wp_batch, Wsp_batch;
|
||||
if (!ec_point_mul_scalar_public_batch(group, &Tp_batch,
|
||||
/*g_scalar=*/NULL, Tps, es,
|
||||
num_to_issue) ||
|
||||
!ec_point_mul_scalar_public_batch(group, &Sp_batch,
|
||||
/*g_scalar=*/NULL, Sps, es,
|
||||
num_to_issue) ||
|
||||
!ec_point_mul_scalar_public_batch(group, &Wp_batch,
|
||||
/*g_scalar=*/NULL, Wps, es,
|
||||
num_to_issue) ||
|
||||
!ec_point_mul_scalar_public_batch(group, &Wsp_batch,
|
||||
/*g_scalar=*/NULL, Wsps, es,
|
||||
num_to_issue)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
CBB proof;
|
||||
if (!CBB_add_u16_length_prefixed(cbb, &proof) ||
|
||||
!dleq_generate(method, &proof, key, &Tp_batch, &Sp_batch, &Wp_batch,
|
||||
&Wsp_batch, private_metadata) ||
|
||||
!CBB_flush(cbb)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// Skip over any unused requests.
|
||||
@@ -890,36 +870,29 @@ static STACK_OF(TRUST_TOKEN) *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EC_RAW_POINT *Tps = NULL;
|
||||
EC_RAW_POINT *Sps = NULL;
|
||||
EC_RAW_POINT *Wps = NULL;
|
||||
EC_RAW_POINT *Wsps = NULL;
|
||||
EC_SCALAR *es = NULL;
|
||||
if (count > ((size_t)-1) / sizeof(EC_RAW_POINT) ||
|
||||
count > ((size_t)-1) / sizeof(EC_SCALAR)) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
|
||||
return 0;
|
||||
}
|
||||
EC_RAW_POINT *Tps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT));
|
||||
EC_RAW_POINT *Sps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT));
|
||||
EC_RAW_POINT *Wps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT));
|
||||
EC_RAW_POINT *Wsps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT));
|
||||
EC_SCALAR *es = OPENSSL_malloc(count * sizeof(EC_SCALAR));
|
||||
CBB batch_cbb;
|
||||
CBB_zero(&batch_cbb);
|
||||
if (method->batched_proof) {
|
||||
if (count > ((size_t)-1) / sizeof(EC_RAW_POINT) ||
|
||||
count > ((size_t)-1) / sizeof(EC_SCALAR)) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_OVERFLOW);
|
||||
goto err;
|
||||
}
|
||||
Tps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT));
|
||||
Sps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT));
|
||||
Wps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT));
|
||||
Wsps = OPENSSL_malloc(count * sizeof(EC_RAW_POINT));
|
||||
es = OPENSSL_malloc(count * sizeof(EC_SCALAR));
|
||||
if (!Tps ||
|
||||
!Sps ||
|
||||
!Wps ||
|
||||
!Wsps ||
|
||||
!es ||
|
||||
!CBB_init(&batch_cbb, 0) ||
|
||||
!point_to_cbb(&batch_cbb, method->group, &key->pubs) ||
|
||||
!point_to_cbb(&batch_cbb, method->group, &key->pub0) ||
|
||||
!point_to_cbb(&batch_cbb, method->group, &key->pub1)) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!Tps ||
|
||||
!Sps ||
|
||||
!Wps ||
|
||||
!Wsps ||
|
||||
!es ||
|
||||
!CBB_init(&batch_cbb, 0) ||
|
||||
!point_to_cbb(&batch_cbb, method->group, &key->pubs) ||
|
||||
!point_to_cbb(&batch_cbb, method->group, &key->pub0) ||
|
||||
!point_to_cbb(&batch_cbb, method->group, &key->pub1)) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
@@ -928,7 +901,6 @@ static STACK_OF(TRUST_TOKEN) *
|
||||
|
||||
uint8_t s[PMBTOKEN_NONCE_SIZE];
|
||||
EC_AFFINE Wp_affine, Wsp_affine;
|
||||
CBS proof;
|
||||
if (!CBS_copy_bytes(cbs, s, PMBTOKEN_NONCE_SIZE) ||
|
||||
!cbs_get_prefixed_point(cbs, group, &Wp_affine) ||
|
||||
!cbs_get_prefixed_point(cbs, group, &Wsp_affine)) {
|
||||
@@ -936,50 +908,29 @@ static STACK_OF(TRUST_TOKEN) *
|
||||
goto err;
|
||||
}
|
||||
|
||||
EC_RAW_POINT Tp, Wp, Wsp, Sp;
|
||||
ec_affine_to_jacobian(group, &Tp, &pretoken->Tp);
|
||||
ec_affine_to_jacobian(group, &Wp, &Wp_affine);
|
||||
ec_affine_to_jacobian(group, &Wsp, &Wsp_affine);
|
||||
if (!method->hash_s(group, &Sp, &pretoken->Tp, s)) {
|
||||
ec_affine_to_jacobian(group, &Tps[i], &pretoken->Tp);
|
||||
ec_affine_to_jacobian(group, &Wps[i], &Wp_affine);
|
||||
ec_affine_to_jacobian(group, &Wsps[i], &Wsp_affine);
|
||||
if (!method->hash_s(group, &Sps[i], &pretoken->Tp, s)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!method->batched_proof) {
|
||||
if(!CBS_get_u16_length_prefixed(cbs, &proof)) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!dleq_verify(method, &proof, key, &Tp, &Sp, &Wp, &Wsp)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (CBS_len(&proof) != 0) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
EC_AFFINE Sp_affine;
|
||||
if (!point_to_cbb(&batch_cbb, group, &pretoken->Tp) ||
|
||||
!ec_jacobian_to_affine(group, &Sp_affine, &Sp) ||
|
||||
!point_to_cbb(&batch_cbb, group, &Sp_affine) ||
|
||||
!point_to_cbb(&batch_cbb, group, &Wp_affine) ||
|
||||
!point_to_cbb(&batch_cbb, group, &Wsp_affine)) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
Tps[i] = Tp;
|
||||
Sps[i] = Sp;
|
||||
Wps[i] = Wp;
|
||||
Wsps[i] = Wsp;
|
||||
EC_AFFINE Sp_affine;
|
||||
if (!point_to_cbb(&batch_cbb, group, &pretoken->Tp) ||
|
||||
!ec_jacobian_to_affine(group, &Sp_affine, &Sps[i]) ||
|
||||
!point_to_cbb(&batch_cbb, group, &Sp_affine) ||
|
||||
!point_to_cbb(&batch_cbb, group, &Wp_affine) ||
|
||||
!point_to_cbb(&batch_cbb, group, &Wsp_affine)) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
// Unblind the token.
|
||||
EC_RAW_POINT jacobians[3];
|
||||
EC_AFFINE affines[3];
|
||||
if (!ec_point_mul_scalar(group, &jacobians[0], &Sp, &pretoken->r) ||
|
||||
!ec_point_mul_scalar(group, &jacobians[1], &Wp, &pretoken->r) ||
|
||||
!ec_point_mul_scalar(group, &jacobians[2], &Wsp, &pretoken->r) ||
|
||||
if (!ec_point_mul_scalar(group, &jacobians[0], &Sps[i], &pretoken->r) ||
|
||||
!ec_point_mul_scalar(group, &jacobians[1], &Wps[i], &pretoken->r) ||
|
||||
!ec_point_mul_scalar(group, &jacobians[2], &Wsps[i], &pretoken->r) ||
|
||||
!ec_jacobian_to_affine_batch(group, affines, jacobians, 3)) {
|
||||
goto err;
|
||||
}
|
||||
@@ -1018,32 +969,30 @@ static STACK_OF(TRUST_TOKEN) *
|
||||
// The DLEQ batching construction is described in appendix B of
|
||||
// https://eprint.iacr.org/2020/072/20200324:214215. Note the additional
|
||||
// computations all act on public inputs.
|
||||
if (method->batched_proof) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (!hash_c_batch(method, &es[i], &batch_cbb, i)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
EC_RAW_POINT Tp_batch, Sp_batch, Wp_batch, Wsp_batch;
|
||||
if (!ec_point_mul_scalar_public_batch(group, &Tp_batch,
|
||||
/*g_scalar=*/NULL, Tps, es, count) ||
|
||||
!ec_point_mul_scalar_public_batch(group, &Sp_batch,
|
||||
/*g_scalar=*/NULL, Sps, es, count) ||
|
||||
!ec_point_mul_scalar_public_batch(group, &Wp_batch,
|
||||
/*g_scalar=*/NULL, Wps, es, count) ||
|
||||
!ec_point_mul_scalar_public_batch(group, &Wsp_batch,
|
||||
/*g_scalar=*/NULL, Wsps, es, count)) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (!hash_c_batch(method, &es[i], &batch_cbb, i)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
CBS proof;
|
||||
if (!CBS_get_u16_length_prefixed(cbs, &proof) ||
|
||||
!dleq_verify(method, &proof, key, &Tp_batch, &Sp_batch, &Wp_batch,
|
||||
&Wsp_batch) ||
|
||||
CBS_len(&proof) != 0) {
|
||||
goto err;
|
||||
}
|
||||
EC_RAW_POINT Tp_batch, Sp_batch, Wp_batch, Wsp_batch;
|
||||
if (!ec_point_mul_scalar_public_batch(group, &Tp_batch,
|
||||
/*g_scalar=*/NULL, Tps, es, count) ||
|
||||
!ec_point_mul_scalar_public_batch(group, &Sp_batch,
|
||||
/*g_scalar=*/NULL, Sps, es, count) ||
|
||||
!ec_point_mul_scalar_public_batch(group, &Wp_batch,
|
||||
/*g_scalar=*/NULL, Wps, es, count) ||
|
||||
!ec_point_mul_scalar_public_batch(group, &Wsp_batch,
|
||||
/*g_scalar=*/NULL, Wsps, es, count)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
CBS proof;
|
||||
if (!CBS_get_u16_length_prefixed(cbs, &proof) ||
|
||||
!dleq_verify(method, &proof, key, &Tp_batch, &Sp_batch, &Wp_batch,
|
||||
&Wsp_batch) ||
|
||||
CBS_len(&proof) != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ok = 1;
|
||||
@@ -1127,202 +1076,6 @@ static int pmbtoken_read(const PMBTOKEN_METHOD *method,
|
||||
}
|
||||
|
||||
|
||||
// PMBTokens experiment v0.
|
||||
|
||||
static int pmbtoken_exp0_hash_t(const EC_GROUP *group, EC_RAW_POINT *out,
|
||||
const uint8_t t[PMBTOKEN_NONCE_SIZE]) {
|
||||
const uint8_t kHashTLabel[] = "PMBTokensV0 HashT";
|
||||
return ec_hash_to_curve_p521_xmd_sha512_sswu_draft06(
|
||||
group, out, kHashTLabel, sizeof(kHashTLabel), t, PMBTOKEN_NONCE_SIZE);
|
||||
}
|
||||
|
||||
static int pmbtoken_exp0_hash_s(const EC_GROUP *group, EC_RAW_POINT *out,
|
||||
const EC_AFFINE *t,
|
||||
const uint8_t s[PMBTOKEN_NONCE_SIZE]) {
|
||||
const uint8_t kHashSLabel[] = "PMBTokensV0 HashS";
|
||||
int ret = 0;
|
||||
CBB cbb;
|
||||
uint8_t *buf = NULL;
|
||||
size_t len;
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
!point_to_cbb(&cbb, group, t) ||
|
||||
!CBB_add_bytes(&cbb, s, PMBTOKEN_NONCE_SIZE) ||
|
||||
!CBB_finish(&cbb, &buf, &len) ||
|
||||
!ec_hash_to_curve_p521_xmd_sha512_sswu_draft06(
|
||||
group, out, kHashSLabel, sizeof(kHashSLabel), buf, len)) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
OPENSSL_free(buf);
|
||||
CBB_cleanup(&cbb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pmbtoken_exp0_hash_c(const EC_GROUP *group, EC_SCALAR *out,
|
||||
uint8_t *buf, size_t len) {
|
||||
const uint8_t kHashCLabel[] = "PMBTokensV0 HashC";
|
||||
return ec_hash_to_scalar_p521_xmd_sha512_draft06(
|
||||
group, out, kHashCLabel, sizeof(kHashCLabel), buf, len);
|
||||
}
|
||||
|
||||
// H for PMBTokens v0 was generated with the following Python code.
|
||||
/*
|
||||
import hashlib
|
||||
|
||||
SEED_H = 'PrivacyPass H'
|
||||
|
||||
A = -3
|
||||
B = 0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00
|
||||
P = 2**521 - 1
|
||||
|
||||
def get_y(x):
|
||||
y2 = (x**3 + A*x + B) % P
|
||||
y = pow(y2, (P+1)/4, P)
|
||||
if (y*y) % P != y2:
|
||||
raise ValueError("point not on curve")
|
||||
return y
|
||||
|
||||
def bit(h,i):
|
||||
return (ord(h[i/8]) >> (i%8)) & 1
|
||||
|
||||
b = 521
|
||||
def decode_point(so):
|
||||
s = hashlib.sha256(so + '0').digest() + hashlib.sha256(so + '1').digest() + \
|
||||
hashlib.sha256(so + '2').digest()
|
||||
|
||||
x = 0
|
||||
for i in range(0,b):
|
||||
x = x + (long(bit(s,i))<<i)
|
||||
if x >= P:
|
||||
raise ValueError("x out of range")
|
||||
y = get_y(x)
|
||||
if y & 1 != bit(s,b-1): y = P-y
|
||||
return (x, y)
|
||||
|
||||
|
||||
def gen_point(seed):
|
||||
v = hashlib.sha256(seed).digest()
|
||||
it = 1
|
||||
while True:
|
||||
try:
|
||||
x,y = decode_point(v)
|
||||
except Exception, e:
|
||||
print e
|
||||
it += 1
|
||||
v = hashlib.sha256(v).digest()
|
||||
continue
|
||||
print "Found in %d iterations:" % it
|
||||
print " x = %d" % x
|
||||
print " y = %d" % y
|
||||
print " Encoded (hex): (%x, %x)" % (x, y)
|
||||
return (x, y)
|
||||
|
||||
if __name__ == "__main__":
|
||||
gen_point(SEED_H)
|
||||
*/
|
||||
static int pmbtoken_exp0_ok = 0;
|
||||
static PMBTOKEN_METHOD pmbtoken_exp0_method;
|
||||
static CRYPTO_once_t pmbtoken_exp0_method_once = CRYPTO_ONCE_INIT;
|
||||
|
||||
static void pmbtoken_exp0_init_method_impl(void) {
|
||||
static const uint8_t kH[] = {
|
||||
0x04, 0x01, 0xf0, 0xa9, 0xf7, 0x9e, 0xbc, 0x12, 0x6c, 0xef, 0xd1, 0xab,
|
||||
0x29, 0x10, 0x03, 0x6f, 0x4e, 0xf5, 0xbd, 0xeb, 0x0f, 0x6b, 0xc0, 0x5c,
|
||||
0x0e, 0xce, 0xfe, 0x59, 0x45, 0xd1, 0x3e, 0x25, 0x33, 0x7e, 0x4c, 0xda,
|
||||
0x64, 0x53, 0x54, 0x4e, 0xf9, 0x76, 0x0d, 0x6d, 0xc5, 0x39, 0x2a, 0xd4,
|
||||
0xce, 0x84, 0x6e, 0x31, 0xc2, 0x86, 0x21, 0xf9, 0x5c, 0x98, 0xb9, 0x3d,
|
||||
0x01, 0x74, 0x9f, 0xc5, 0x1e, 0x47, 0x24, 0x00, 0x5c, 0x17, 0x62, 0x51,
|
||||
0x7d, 0x32, 0x5e, 0x29, 0xac, 0x52, 0x14, 0x75, 0x6f, 0x36, 0xd9, 0xc7,
|
||||
0xfa, 0xbb, 0xa9, 0x3b, 0x9d, 0x70, 0x49, 0x1e, 0xb4, 0x53, 0xbc, 0x55,
|
||||
0xea, 0xad, 0x8f, 0x26, 0x1d, 0xe0, 0xbc, 0xf3, 0x50, 0x5c, 0x7e, 0x66,
|
||||
0x41, 0xb5, 0x61, 0x70, 0x12, 0x72, 0xac, 0x6a, 0xb0, 0x6e, 0x78, 0x3d,
|
||||
0x17, 0x08, 0xe3, 0xdf, 0x3c, 0xff, 0xa6, 0xa0, 0xea, 0x96, 0x67, 0x92,
|
||||
0xcd,
|
||||
};
|
||||
|
||||
pmbtoken_exp0_ok =
|
||||
pmbtoken_init_method(&pmbtoken_exp0_method, NID_secp521r1, kH, sizeof(kH),
|
||||
pmbtoken_exp0_hash_t, pmbtoken_exp0_hash_s,
|
||||
pmbtoken_exp0_hash_c, /*batched_proof=*/0);
|
||||
}
|
||||
|
||||
static int pmbtoken_exp0_init_method(void) {
|
||||
CRYPTO_once(&pmbtoken_exp0_method_once, pmbtoken_exp0_init_method_impl);
|
||||
if (!pmbtoken_exp0_ok) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int pmbtoken_exp0_generate_key(CBB *out_private, CBB *out_public) {
|
||||
if (!pmbtoken_exp0_init_method()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pmbtoken_generate_key(&pmbtoken_exp0_method, out_private, out_public);
|
||||
}
|
||||
|
||||
int pmbtoken_exp0_client_key_from_bytes(PMBTOKEN_CLIENT_KEY *key,
|
||||
const uint8_t *in, size_t len) {
|
||||
if (!pmbtoken_exp0_init_method()) {
|
||||
return 0;
|
||||
}
|
||||
return pmbtoken_client_key_from_bytes(&pmbtoken_exp0_method, key, in, len);
|
||||
}
|
||||
|
||||
int pmbtoken_exp0_issuer_key_from_bytes(PMBTOKEN_ISSUER_KEY *key,
|
||||
const uint8_t *in, size_t len) {
|
||||
if (!pmbtoken_exp0_init_method()) {
|
||||
return 0;
|
||||
}
|
||||
return pmbtoken_issuer_key_from_bytes(&pmbtoken_exp0_method, key, in, len);
|
||||
}
|
||||
|
||||
STACK_OF(PMBTOKEN_PRETOKEN) * pmbtoken_exp0_blind(CBB *cbb, size_t count) {
|
||||
if (!pmbtoken_exp0_init_method()) {
|
||||
return NULL;
|
||||
}
|
||||
return pmbtoken_blind(&pmbtoken_exp0_method, cbb, count);
|
||||
}
|
||||
|
||||
int pmbtoken_exp0_sign(const PMBTOKEN_ISSUER_KEY *key, CBB *cbb, CBS *cbs,
|
||||
size_t num_requested, size_t num_to_issue,
|
||||
uint8_t private_metadata) {
|
||||
if (!pmbtoken_exp0_init_method()) {
|
||||
return 0;
|
||||
}
|
||||
return pmbtoken_sign(&pmbtoken_exp0_method, key, cbb, cbs, num_requested,
|
||||
num_to_issue, private_metadata);
|
||||
}
|
||||
|
||||
STACK_OF(TRUST_TOKEN) *
|
||||
pmbtoken_exp0_unblind(const PMBTOKEN_CLIENT_KEY *key,
|
||||
const STACK_OF(PMBTOKEN_PRETOKEN) * pretokens,
|
||||
CBS *cbs, size_t count, uint32_t key_id) {
|
||||
if (!pmbtoken_exp0_init_method()) {
|
||||
return NULL;
|
||||
}
|
||||
return pmbtoken_unblind(&pmbtoken_exp0_method, key, pretokens, cbs, count,
|
||||
key_id);
|
||||
}
|
||||
|
||||
int pmbtoken_exp0_read(const PMBTOKEN_ISSUER_KEY *key,
|
||||
uint8_t out_nonce[PMBTOKEN_NONCE_SIZE],
|
||||
uint8_t *out_private_metadata, const uint8_t *token,
|
||||
size_t token_len) {
|
||||
if (!pmbtoken_exp0_init_method()) {
|
||||
return 0;
|
||||
}
|
||||
return pmbtoken_read(&pmbtoken_exp0_method, key, out_nonce,
|
||||
out_private_metadata, token, token_len);
|
||||
}
|
||||
|
||||
|
||||
// PMBTokens experiment v1.
|
||||
|
||||
static int pmbtoken_exp1_hash_t(const EC_GROUP *group, EC_RAW_POINT *out,
|
||||
@@ -1387,7 +1140,7 @@ static void pmbtoken_exp1_init_method_impl(void) {
|
||||
pmbtoken_exp1_ok =
|
||||
pmbtoken_init_method(&pmbtoken_exp1_method, NID_secp384r1, kH, sizeof(kH),
|
||||
pmbtoken_exp1_hash_t, pmbtoken_exp1_hash_s,
|
||||
pmbtoken_exp1_hash_c, /*batched_proof=*/1);
|
||||
pmbtoken_exp1_hash_c);
|
||||
}
|
||||
|
||||
static int pmbtoken_exp1_init_method(void) {
|
||||
|
||||
@@ -27,21 +27,6 @@
|
||||
// protocol for issuing and redeeming tokens built on top of the PMBTokens
|
||||
// construction.
|
||||
|
||||
const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v0(void) {
|
||||
static const TRUST_TOKEN_METHOD kMethod = {
|
||||
pmbtoken_exp0_generate_key,
|
||||
pmbtoken_exp0_client_key_from_bytes,
|
||||
pmbtoken_exp0_issuer_key_from_bytes,
|
||||
pmbtoken_exp0_blind,
|
||||
pmbtoken_exp0_sign,
|
||||
pmbtoken_exp0_unblind,
|
||||
pmbtoken_exp0_read,
|
||||
0 /* don't use token hash */,
|
||||
0 /* don't use batched proof */,
|
||||
};
|
||||
return &kMethod;
|
||||
}
|
||||
|
||||
const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v1(void) {
|
||||
static const TRUST_TOKEN_METHOD kMethod = {
|
||||
pmbtoken_exp1_generate_key,
|
||||
@@ -51,8 +36,6 @@ const TRUST_TOKEN_METHOD *TRUST_TOKEN_experiment_v1(void) {
|
||||
pmbtoken_exp1_sign,
|
||||
pmbtoken_exp1_unblind,
|
||||
pmbtoken_exp1_read,
|
||||
1 /* use token hash */,
|
||||
1 /* use batched proof */,
|
||||
};
|
||||
return &kMethod;
|
||||
}
|
||||
@@ -597,16 +580,8 @@ int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out,
|
||||
SHA256_Update(&sha_ctx, CBS_data(&token_copy), CBS_len(&token_copy));
|
||||
SHA256_Final(token_hash, &sha_ctx);
|
||||
|
||||
uint8_t metadata_obfuscator;
|
||||
if (ctx->method->use_token_hash) {
|
||||
metadata_obfuscator =
|
||||
get_metadata_obfuscator(ctx->metadata_key, ctx->metadata_key_len,
|
||||
token_hash, sizeof(token_hash));
|
||||
} else {
|
||||
metadata_obfuscator =
|
||||
get_metadata_obfuscator(ctx->metadata_key, ctx->metadata_key_len,
|
||||
CBS_data(&client_data), CBS_len(&client_data));
|
||||
}
|
||||
uint8_t metadata_obfuscator = get_metadata_obfuscator(
|
||||
ctx->metadata_key, ctx->metadata_key_len, token_hash, sizeof(token_hash));
|
||||
|
||||
// The SRR is constructed as per the format described in
|
||||
// https://docs.google.com/document/d/1TNnya6B8pyomDK2F1R9CL3dY10OAmqWlnCxsWyOBDVQ/edit#heading=h.7mkzvhpqb8l5
|
||||
@@ -625,10 +600,7 @@ int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out,
|
||||
assert(strlen(kClientDataLabel) < strlen(kExpiryTimestampLabel));
|
||||
assert(strlen(kPublicLabel) < strlen(kPrivateLabel));
|
||||
|
||||
size_t map_entries = 3;
|
||||
if (ctx->method->use_token_hash) {
|
||||
map_entries = 4;
|
||||
}
|
||||
size_t map_entries = 4;
|
||||
|
||||
if (!CBB_init(&srr, 0) ||
|
||||
!add_cbor_map(&srr, map_entries) || // SRR map
|
||||
@@ -637,20 +609,10 @@ int TRUST_TOKEN_ISSUER_redeem(const TRUST_TOKEN_ISSUER *ctx, uint8_t **out,
|
||||
!add_cbor_text(&srr, kPublicLabel, strlen(kPublicLabel)) ||
|
||||
!add_cbor_int(&srr, public_metadata) ||
|
||||
!add_cbor_text(&srr, kPrivateLabel, strlen(kPrivateLabel)) ||
|
||||
!add_cbor_int(&srr, private_metadata ^ metadata_obfuscator)) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ctx->method->use_token_hash) {
|
||||
if (!add_cbor_text(&srr, kTokenHashLabel, strlen(kTokenHashLabel)) ||
|
||||
!add_cbor_bytes(&srr, token_hash, sizeof(token_hash))) {
|
||||
OPENSSL_PUT_ERROR(TRUST_TOKEN, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!add_cbor_text(&srr, kClientDataLabel, strlen(kClientDataLabel)) ||
|
||||
!add_cbor_int(&srr, private_metadata ^ metadata_obfuscator) ||
|
||||
!add_cbor_text(&srr, kTokenHashLabel, strlen(kTokenHashLabel)) ||
|
||||
!add_cbor_bytes(&srr, token_hash, sizeof(token_hash)) ||
|
||||
!add_cbor_text(&srr, kClientDataLabel, strlen(kClientDataLabel)) ||
|
||||
!CBB_add_bytes(&srr, CBS_data(&client_data), CBS_len(&client_data)) ||
|
||||
!add_cbor_text(&srr, kExpiryTimestampLabel,
|
||||
strlen(kExpiryTimestampLabel)) ||
|
||||
|
||||
@@ -44,18 +44,6 @@ BSSL_NAMESPACE_BEGIN
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(TrustTokenTest, KeyGenExp0) {
|
||||
uint8_t priv_key[TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE];
|
||||
uint8_t pub_key[TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE];
|
||||
size_t priv_key_len, pub_key_len;
|
||||
ASSERT_TRUE(TRUST_TOKEN_generate_key(
|
||||
TRUST_TOKEN_experiment_v0(), priv_key, &priv_key_len,
|
||||
TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE, pub_key, &pub_key_len,
|
||||
TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE, 0x0001));
|
||||
ASSERT_EQ(400u, priv_key_len);
|
||||
ASSERT_EQ(409u, pub_key_len);
|
||||
}
|
||||
|
||||
TEST(TrustTokenTest, KeyGenExp1) {
|
||||
uint8_t priv_key[TRUST_TOKEN_MAX_PRIVATE_KEY_SIZE];
|
||||
uint8_t pub_key[TRUST_TOKEN_MAX_PUBLIC_KEY_SIZE];
|
||||
@@ -91,7 +79,7 @@ TEST(TrustTokenTest, HExp1) {
|
||||
}
|
||||
|
||||
static std::vector<const TRUST_TOKEN_METHOD *> AllMethods() {
|
||||
return {TRUST_TOKEN_experiment_v0(), TRUST_TOKEN_experiment_v1()};
|
||||
return {TRUST_TOKEN_experiment_v1()};
|
||||
}
|
||||
|
||||
class TrustTokenProtocolTestBase : public ::testing::Test {
|
||||
@@ -454,14 +442,7 @@ TEST_P(TrustTokenMetadataTest, SetAndGetMetadata) {
|
||||
const uint8_t kClientData[] = "\x70TEST CLIENT DATA";
|
||||
uint64_t kRedemptionTime = 13374242;
|
||||
|
||||
const uint8_t kExpectedSRRNoTokenHash[] =
|
||||
"\xa3\x68\x6d\x65\x74\x61\x64\x61\x74\x61\xa2\x66\x70\x75\x62\x6c\x69"
|
||||
"\x63\x00\x67\x70\x72\x69\x76\x61\x74\x65\x00\x6b\x63\x6c\x69\x65\x6e"
|
||||
"\x74\x2d\x64\x61\x74\x61\x70\x54\x45\x53\x54\x20\x43\x4c\x49\x45\x4e"
|
||||
"\x54\x20\x44\x41\x54\x41\x70\x65\x78\x70\x69\x72\x79\x2d\x74\x69\x6d"
|
||||
"\x65\x73\x74\x61\x6d\x70\x1a\x00\xcc\x15\x7a";
|
||||
|
||||
const uint8_t kExpectedSRRTokenHash[] =
|
||||
const uint8_t kExpectedSRR[] =
|
||||
"\xa4\x68\x6d\x65\x74\x61\x64\x61\x74\x61\xa2\x66\x70\x75\x62\x6c\x69"
|
||||
"\x63\x00\x67\x70\x72\x69\x76\x61\x74\x65\x00\x6a\x74\x6f\x6b\x65\x6e"
|
||||
"\x2d\x68\x61\x73\x68\x58\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
@@ -498,50 +479,33 @@ TEST_P(TrustTokenMetadataTest, SetAndGetMetadata) {
|
||||
bssl::UniquePtr<uint8_t> free_srr(srr);
|
||||
bssl::UniquePtr<uint8_t> free_sig(sig);
|
||||
|
||||
if (method()->use_token_hash) {
|
||||
const uint8_t kTokenHashDSTLabel[] = "TrustTokenV0 TokenHash";
|
||||
uint8_t token_hash[SHA256_DIGEST_LENGTH];
|
||||
SHA256_CTX sha_ctx;
|
||||
SHA256_Init(&sha_ctx);
|
||||
SHA256_Update(&sha_ctx, kTokenHashDSTLabel, sizeof(kTokenHashDSTLabel));
|
||||
SHA256_Update(&sha_ctx, token->data, token->len);
|
||||
SHA256_Final(token_hash, &sha_ctx);
|
||||
const uint8_t kTokenHashDSTLabel[] = "TrustTokenV0 TokenHash";
|
||||
uint8_t token_hash[SHA256_DIGEST_LENGTH];
|
||||
SHA256_CTX sha_ctx;
|
||||
SHA256_Init(&sha_ctx);
|
||||
SHA256_Update(&sha_ctx, kTokenHashDSTLabel, sizeof(kTokenHashDSTLabel));
|
||||
SHA256_Update(&sha_ctx, token->data, token->len);
|
||||
SHA256_Final(token_hash, &sha_ctx);
|
||||
|
||||
// Check the token hash is in the SRR.
|
||||
ASSERT_EQ(Bytes(token_hash), Bytes(srr + 41, sizeof(token_hash)));
|
||||
// Check the token hash is in the SRR.
|
||||
ASSERT_EQ(Bytes(token_hash), Bytes(srr + 41, sizeof(token_hash)));
|
||||
|
||||
uint8_t decode_private_metadata;
|
||||
ASSERT_TRUE(TRUST_TOKEN_decode_private_metadata(
|
||||
method(), &decode_private_metadata, metadata_key,
|
||||
sizeof(metadata_key), token_hash, sizeof(token_hash), srr[27]));
|
||||
ASSERT_EQ(srr[18], public_metadata());
|
||||
ASSERT_EQ(decode_private_metadata, private_metadata());
|
||||
uint8_t decode_private_metadata;
|
||||
ASSERT_TRUE(TRUST_TOKEN_decode_private_metadata(
|
||||
method(), &decode_private_metadata, metadata_key, sizeof(metadata_key),
|
||||
token_hash, sizeof(token_hash), srr[27]));
|
||||
ASSERT_EQ(srr[18], public_metadata());
|
||||
ASSERT_EQ(decode_private_metadata, private_metadata());
|
||||
|
||||
// Clear out the metadata bits.
|
||||
srr[18] = 0;
|
||||
srr[27] = 0;
|
||||
// Clear out the metadata bits.
|
||||
srr[18] = 0;
|
||||
srr[27] = 0;
|
||||
|
||||
// Clear out the token hash.
|
||||
OPENSSL_memset(srr + 41, 0, sizeof(token_hash));
|
||||
// Clear out the token hash.
|
||||
OPENSSL_memset(srr + 41, 0, sizeof(token_hash));
|
||||
|
||||
ASSERT_EQ(Bytes(kExpectedSRRTokenHash, sizeof(kExpectedSRRTokenHash) - 1),
|
||||
Bytes(srr, srr_len));
|
||||
} else {
|
||||
uint8_t decode_private_metadata;
|
||||
ASSERT_TRUE(TRUST_TOKEN_decode_private_metadata(
|
||||
method(), &decode_private_metadata, metadata_key,
|
||||
sizeof(metadata_key), kClientData, sizeof(kClientData) - 1, srr[27]));
|
||||
ASSERT_EQ(srr[18], public_metadata());
|
||||
ASSERT_EQ(decode_private_metadata, private_metadata());
|
||||
|
||||
// Clear out the metadata bits.
|
||||
srr[18] = 0;
|
||||
srr[27] = 0;
|
||||
|
||||
ASSERT_EQ(
|
||||
Bytes(kExpectedSRRNoTokenHash, sizeof(kExpectedSRRNoTokenHash) - 1),
|
||||
Bytes(srr, srr_len));
|
||||
}
|
||||
ASSERT_EQ(Bytes(kExpectedSRR, sizeof(kExpectedSRR) - 1),
|
||||
Bytes(srr, srr_len));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -607,23 +571,14 @@ TEST_P(TrustTokenMetadataTest, TruncatedProof) {
|
||||
ASSERT_TRUE(CBB_add_u16(bad_response.get(), CBS_len(&tmp)));
|
||||
ASSERT_TRUE(
|
||||
CBB_add_bytes(bad_response.get(), CBS_data(&tmp), CBS_len(&tmp)));
|
||||
if (!method()->batched_proof) {
|
||||
ASSERT_TRUE(CBS_get_u16_length_prefixed(&real_response, &tmp));
|
||||
CBB dleq;
|
||||
ASSERT_TRUE(CBB_add_u16_length_prefixed(bad_response.get(), &dleq));
|
||||
ASSERT_TRUE(CBB_add_bytes(&dleq, CBS_data(&tmp), CBS_len(&tmp) - 2));
|
||||
ASSERT_TRUE(CBB_flush(bad_response.get()));
|
||||
}
|
||||
}
|
||||
|
||||
if (method()->batched_proof) {
|
||||
CBS tmp;
|
||||
ASSERT_TRUE(CBS_get_u16_length_prefixed(&real_response, &tmp));
|
||||
CBB dleq;
|
||||
ASSERT_TRUE(CBB_add_u16_length_prefixed(bad_response.get(), &dleq));
|
||||
ASSERT_TRUE(CBB_add_bytes(&dleq, CBS_data(&tmp), CBS_len(&tmp) - 2));
|
||||
ASSERT_TRUE(CBB_flush(bad_response.get()));
|
||||
}
|
||||
CBS tmp;
|
||||
ASSERT_TRUE(CBS_get_u16_length_prefixed(&real_response, &tmp));
|
||||
CBB dleq;
|
||||
ASSERT_TRUE(CBB_add_u16_length_prefixed(bad_response.get(), &dleq));
|
||||
ASSERT_TRUE(CBB_add_bytes(&dleq, CBS_data(&tmp), CBS_len(&tmp) - 2));
|
||||
ASSERT_TRUE(CBB_flush(bad_response.get()));
|
||||
|
||||
uint8_t *bad_buf;
|
||||
size_t bad_len;
|
||||
@@ -675,25 +630,15 @@ TEST_P(TrustTokenMetadataTest, ExcessDataProof) {
|
||||
ASSERT_TRUE(CBB_add_u16(bad_response.get(), CBS_len(&tmp)));
|
||||
ASSERT_TRUE(
|
||||
CBB_add_bytes(bad_response.get(), CBS_data(&tmp), CBS_len(&tmp)));
|
||||
if (!method()->batched_proof) {
|
||||
ASSERT_TRUE(CBS_get_u16_length_prefixed(&real_response, &tmp));
|
||||
CBB dleq;
|
||||
ASSERT_TRUE(CBB_add_u16_length_prefixed(bad_response.get(), &dleq));
|
||||
ASSERT_TRUE(CBB_add_bytes(&dleq, CBS_data(&tmp), CBS_len(&tmp)));
|
||||
ASSERT_TRUE(CBB_add_u16(&dleq, 42));
|
||||
ASSERT_TRUE(CBB_flush(bad_response.get()));
|
||||
}
|
||||
}
|
||||
|
||||
if (method()->batched_proof) {
|
||||
CBS tmp;
|
||||
ASSERT_TRUE(CBS_get_u16_length_prefixed(&real_response, &tmp));
|
||||
CBB dleq;
|
||||
ASSERT_TRUE(CBB_add_u16_length_prefixed(bad_response.get(), &dleq));
|
||||
ASSERT_TRUE(CBB_add_bytes(&dleq, CBS_data(&tmp), CBS_len(&tmp)));
|
||||
ASSERT_TRUE(CBB_add_u16(&dleq, 42));
|
||||
ASSERT_TRUE(CBB_flush(bad_response.get()));
|
||||
}
|
||||
CBS tmp;
|
||||
ASSERT_TRUE(CBS_get_u16_length_prefixed(&real_response, &tmp));
|
||||
CBB dleq;
|
||||
ASSERT_TRUE(CBB_add_u16_length_prefixed(bad_response.get(), &dleq));
|
||||
ASSERT_TRUE(CBB_add_bytes(&dleq, CBS_data(&tmp), CBS_len(&tmp)));
|
||||
ASSERT_TRUE(CBB_add_u16(&dleq, 42));
|
||||
ASSERT_TRUE(CBB_flush(bad_response.get()));
|
||||
|
||||
uint8_t *bad_buf;
|
||||
size_t bad_len;
|
||||
|
||||
@@ -296,7 +296,7 @@ static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf,
|
||||
*/
|
||||
|
||||
static int do_dump(unsigned long lflags, char_io *io_ch, void *arg,
|
||||
ASN1_STRING *str)
|
||||
const ASN1_STRING *str)
|
||||
{
|
||||
/*
|
||||
* Placing the ASN1_STRING in a temp ASN1_TYPE allows the DER encoding to
|
||||
@@ -354,7 +354,7 @@ static const signed char tag2nbyte[] = {
|
||||
*/
|
||||
|
||||
static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags,
|
||||
ASN1_STRING *str)
|
||||
const ASN1_STRING *str)
|
||||
{
|
||||
int outlen, len;
|
||||
int type;
|
||||
@@ -610,13 +610,13 @@ int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent,
|
||||
}
|
||||
#endif
|
||||
|
||||
int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags)
|
||||
int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, unsigned long flags)
|
||||
{
|
||||
return do_print_ex(send_bio_chars, out, flags, str);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_FP_API
|
||||
int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags)
|
||||
int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, unsigned long flags)
|
||||
{
|
||||
return do_print_ex(send_fp_chars, fp, flags, str);
|
||||
}
|
||||
|
||||
@@ -142,6 +142,14 @@ int x509_digest_verify_init(EVP_MD_CTX *ctx, X509_ALGOR *sigalg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* RSA signature algorithms include an explicit NULL parameter but we also
|
||||
* accept omitted values for compatibility. Other algorithms must omit it. */
|
||||
if (sigalg->parameter != NULL && (pkey_nid != EVP_PKEY_RSA ||
|
||||
sigalg->parameter->type != V_ASN1_NULL)) {
|
||||
OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Otherwise, initialize with the digest from the OID. */
|
||||
const EVP_MD *digest = EVP_get_digestbynid(digest_nid);
|
||||
if (digest == NULL) {
|
||||
|
||||
@@ -123,7 +123,7 @@ typedef struct {
|
||||
int exp_count;
|
||||
} tag_exp_arg;
|
||||
|
||||
static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth,
|
||||
static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth,
|
||||
int *perr);
|
||||
static int bitstr_cb(const char *elem, int len, void *bitstr);
|
||||
static int asn1_cb(const char *elem, int len, void *bitstr);
|
||||
@@ -136,7 +136,7 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
|
||||
static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
|
||||
static int asn1_str2tag(const char *tagstr, int len);
|
||||
|
||||
ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)
|
||||
ASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf)
|
||||
{
|
||||
X509V3_CTX cnf;
|
||||
|
||||
@@ -147,7 +147,7 @@ ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf)
|
||||
return ASN1_generate_v3(str, &cnf);
|
||||
}
|
||||
|
||||
ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
|
||||
ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf)
|
||||
{
|
||||
int err = 0;
|
||||
ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err);
|
||||
@@ -156,7 +156,7 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth,
|
||||
static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth,
|
||||
int *perr)
|
||||
{
|
||||
ASN1_TYPE *ret;
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBdTCCARugAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ
|
||||
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj
|
||||
opP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjODA2MA4G
|
||||
A1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD
|
||||
AQH/MAoGCCqGSM49BAMCA0gAMEUCIDkCS9RrLeO556C9apswg90ZdI2kn3ru31bp
|
||||
a4Rqp82BAiEAqJn5GbUzqjVaI5UthWdcu1zmpdTJntbheeNstXa7k+E=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBhTCCASugAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ
|
||||
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj
|
||||
opP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjSDBGMA4G
|
||||
A1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD
|
||||
AQH/MA4GA1UdIwQHSU5WQUxJRDAKBggqhkjOPQQDAgNIADBFAiEAl5TMKihFw6jD
|
||||
ajc1I7R177t3d4HyW7qCB/M3PHu9HDsCIDI0oBBsuXAHX43N1Jx8LO0sMAzujYom
|
||||
/NZn/qBanQnZ
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,10 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBdTCCARqgAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ
|
||||
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj
|
||||
opP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjNzA1MA4G
|
||||
A1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHRMEB0lOVkFM
|
||||
SUQwCgYIKoZIzj0EAwIDSQAwRgIhAK/zCwmg3s63Ndeg9piiBbMsUF6ZPcNFltEa
|
||||
3cKSMPthAiEAkMq/CmljQigMgXVWOhacYeRLyzZyi2i9hOjrCeKFuno=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,10 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbzCCARagAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ
|
||||
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj
|
||||
opP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjMzAxMA4G
|
||||
A1UdDwEB/wQEAwICBDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdJQQHSU5WQUxJRDAK
|
||||
BggqhkjOPQQDAgNHADBEAiAGr6/3ad6TX4h/HgD5oFiifT7SsRzYVD1yvfyHEYRI
|
||||
qgIgYDbO0XKLN9kSUF8ZBaLPyC1AIbw+m9cQy4/GaJuzxH4=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,10 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBdDCCARugAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ
|
||||
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj
|
||||
opP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjODA2MBMG
|
||||
A1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PBAdJTlZB
|
||||
TElEMAoGCCqGSM49BAMCA0cAMEQCIE1gJ4wr8D0UPRfhQ5sx1WJWEOc+IEtktigk
|
||||
giSupcouAiBFa441h0NvODAwsb39sQ/uaUhucb11vwKSZItwViMp/w==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBhTCCASugAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ
|
||||
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj
|
||||
opP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjSDBGMA4G
|
||||
A1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD
|
||||
AQH/MA4GA1UdHgQHSU5WQUxJRDAKBggqhkjOPQQDAgNIADBFAiB7QedoT6bEccGY
|
||||
/Pofovdtfdzl/AXCtbJjiu59Yt3UTAIhANdfkR5PShTke3o9diKz6G/cVvL9jkF2
|
||||
SKzPRxnRVxNo
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBhDCCASugAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ
|
||||
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj
|
||||
opP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjSDBGMA4G
|
||||
A1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD
|
||||
AQH/MA4GA1UdEQQHSU5WQUxJRDAKBggqhkjOPQQDAgNHADBEAiA4J8X4tb775IOP
|
||||
gBZ8BjlQZXPaRAgO/0d8a5Bgb5j0awIgN1i84TX34Dm8SjArcZLN38mm0zbrvEY0
|
||||
wILouqC75wI=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBhTCCASugAwIBAgIBAjAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowKjEoMCYGA1UEAxMfSW52YWxpZCBFeHRlbnNpb25zIEludGVybWVkaWF0ZTBZ
|
||||
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABOI6fKiM3jFLkLyAn88cvlw4SwxuygRj
|
||||
opP3FFBKHyUQvh3VVvfqSpSCSmp50QiajQ6Dg7CTpVZVVH+bguT7JTCjSDBGMA4G
|
||||
A1UdDwEB/wQEAwICBDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTAD
|
||||
AQH/MA4GA1UdDgQHSU5WQUxJRDAKBggqhkjOPQQDAgNIADBFAiBXToga6ILFNSXj
|
||||
FiwI/ZaZvJubBHzMcrEXtIv85ybV3wIhAL3DMOezrq+dSjf+RdshlTDKwvTY8QYX
|
||||
ehvRzctnYHTd
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBhzCCASygAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw
|
||||
MTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR
|
||||
EvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo1EwTzAOBgNVHQ8BAf8E
|
||||
BAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREE
|
||||
EzARgg93d3cuZXhhbXBsZS5jb20wCgYIKoZIzj0EAwIDSQAwRgIhAJ1DkyH6QYsM
|
||||
bxN/aXhKYGFc1upPpxfHrzmVrVrYq34GAiEAgzAn1bws7mwi4fTBJ4XY44OisCi6
|
||||
gPDLe2H4Esop38o=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBljCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw
|
||||
MTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR
|
||||
EvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo2EwXzAOBgNVHQ8BAf8E
|
||||
BAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREE
|
||||
EzARgg93d3cuZXhhbXBsZS5jb20wDgYDVR0jBAdJTlZBTElEMAoGCCqGSM49BAMC
|
||||
A0gAMEUCIDCqsRJC3IrUHxm5txOfnjrpGmoeSvr1EhVFDhHCuV6GAiEAwJ15sf7y
|
||||
+CGw0rzYTLUHw4nc5aJC9oKOhypg3SrQeGw=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBiDCCAS6gAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw
|
||||
MTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR
|
||||
EvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo1MwUTAOBgNVHQ8BAf8E
|
||||
BAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwGgYDVR0RBBMwEYIPd3d3LmV4YW1w
|
||||
bGUuY29tMA4GA1UdEwQHSU5WQUxJRDAKBggqhkjOPQQDAgNIADBFAiEA6btgd6HI
|
||||
SCvxfnaHqhAiBjLl665JJC/wpSejPlxFmI0CIGZ7pLkRuQKv132ffDBmobAsBBnT
|
||||
YXmJWAHc4rsJCYEx
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBgTCCASegAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw
|
||||
MTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR
|
||||
EvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo0wwSjAOBgNVHQ8BAf8E
|
||||
BAMCAgQwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhhbXBsZS5jb20w
|
||||
DgYDVR0lBAdJTlZBTElEMAoGCCqGSM49BAMCA0gAMEUCIH3jx0mZhPAY2QZHYVPQ
|
||||
ld6RNFGris9CFCD8AMOaZTR+AiEAgr4hSxoIm3g/CVeQkDORqgSrXU0AuVvQL2KO
|
||||
NM5UG1Q=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBhjCCASygAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw
|
||||
MTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR
|
||||
EvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo1EwTzATBgNVHSUEDDAK
|
||||
BggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBoGA1UdEQQTMBGCD3d3dy5leGFtcGxl
|
||||
LmNvbTAOBgNVHQ8EB0lOVkFMSUQwCgYIKoZIzj0EAwIDSAAwRQIgPoSLUcWwjnDx
|
||||
3N+DJPzpgHRRSZtJz6w5njQ+zcyQvrQCIQDThWHI9F5s6xQN42stFw0sasdWFc/9
|
||||
No9QQf1zbGfGDw==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBljCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw
|
||||
MTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR
|
||||
EvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo2EwXzAOBgNVHQ8BAf8E
|
||||
BAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREE
|
||||
EzARgg93d3cuZXhhbXBsZS5jb20wDgYDVR0eBAdJTlZBTElEMAoGCCqGSM49BAMC
|
||||
A0gAMEUCIQCYofdTDXH2HIpc/ZSI6IQVCM0L0/QbKbEOGeAwDtikGAIgV48ECoAt
|
||||
8maDdh8y9qj/TZe6XA39BzkjtsLKhecCuV8=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,10 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBeTCCASCgAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw
|
||||
MTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR
|
||||
EvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo0UwQzAOBgNVHQ8BAf8E
|
||||
BAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAOBgNVHREE
|
||||
B0lOVkFMSUQwCgYIKoZIzj0EAwIDRwAwRAIgDatlhmjkW4lgYc/eyrqJp1kxKrL8
|
||||
0WkPsmdUZmXiI1QCIC1bl+3ponxSaCvn81xKrQzuIq2OzWxy2PTHyNbPnGcz
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBlzCCATygAwIBAgIBAzAKBggqhkjOPQQDAjAqMSgwJgYDVQQDEx9JbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgSW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAw
|
||||
MTAxMDAwMDAwWjAaMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZR
|
||||
EvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5Xo2EwXzAOBgNVHQ8BAf8E
|
||||
BAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREE
|
||||
EzARgg93d3cuZXhhbXBsZS5jb20wDgYDVR0OBAdJTlZBTElEMAoGCCqGSM49BAMC
|
||||
A0kAMEYCIQDNfoYMjJUzrw2qxHKwopCt9lTQIfOCJDzndJwHLSI97gIhAIDRRWkU
|
||||
OpOxpzO5zJtvsPSuFJTPtFi6dKwyZA0VVX5m
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,10 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbjCCAROgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI
|
||||
B6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjoltozgwNjAOBgNVHQ8BAf8E
|
||||
BAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAKBggq
|
||||
hkjOPQQDAgNJADBGAiEAkLonK/c0Wai8LSe6Nhf3ln+dpPxIQD9z0e2bXzgp3ZgC
|
||||
IQDUjv8fhl6szNN6cV4NElVrsuFRigAvt6Z5M132Ybgavw==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBfTCCASOgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI
|
||||
B6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto0gwRjAOBgNVHQ8BAf8E
|
||||
BAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
|
||||
HSMEB0lOVkFMSUQwCgYIKoZIzj0EAwIDSAAwRQIgO/L4Oi8esLDZ5HQgVYd/GUey
|
||||
8yPPRUkfr8+ZH5YJ724CIQCToZDd4kEPRmwjS6R20n5qrDElE4SDBq8cmJEToh57
|
||||
3Q==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,10 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBazCCARKgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI
|
||||
B6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjoltozcwNTAOBgNVHQ8BAf8E
|
||||
BAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYDVR0TBAdJTlZBTElEMAoGCCqG
|
||||
SM49BAMCA0cAMEQCICRNoNJx8TOSe4FKoB7EdfvG56/zvzVK8F4SDV35nbfTAiAF
|
||||
QjSD7CDdbaRQymgX3ojBbAP3hj1fFbCzopKR7UUvxQ==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,10 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBaDCCAQ6gAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI
|
||||
B6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjoltozMwMTAOBgNVHQ8BAf8E
|
||||
BAMCAgQwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHSUEB0lOVkFMSUQwCgYIKoZIzj0E
|
||||
AwIDSAAwRQIgVjuDRpd+kVlqUDJcX899ZsAoIvkSPxo/lCVJ+ae28BkCIQD/9Aig
|
||||
0CaivgJ8Z6mUW9ozp6ClMPfSpCEUtrhm/dg2og==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,10 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbjCCAROgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI
|
||||
B6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjoltozgwNjATBgNVHSUEDDAK
|
||||
BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwQHSU5WQUxJRDAKBggq
|
||||
hkjOPQQDAgNJADBGAiEAmX21h0WJPZ8VjGRaGwYWAh2q7iS0Wzm+besT06qgnPwC
|
||||
IQCEF2G9d/DaDL7H9aw51xA0B+WwHBN5r1kx6b9A5pJVtg==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBfTCCASOgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI
|
||||
B6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto0gwRjAOBgNVHQ8BAf8E
|
||||
BAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
|
||||
HR4EB0lOVkFMSUQwCgYIKoZIzj0EAwIDSAAwRQIhALYRk6SPzWoKF3wLI6N+bWh/
|
||||
iap7zpRrAZqmL3EDTlitAiB0CFMk9r5h/RDkvrP4Z+JZKum9ZVbGew73cdjDVBA3
|
||||
dA==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,10 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBfDCCASOgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI
|
||||
B6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto0gwRjAOBgNVHQ8BAf8E
|
||||
BAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
|
||||
HREEB0lOVkFMSUQwCgYIKoZIzj0EAwIDRwAwRAIgZKRMQGAIoUuzwYQS8UNkuTI5
|
||||
H9kJYpOGZhZ3esyfvC4CIAsJGY8kgzzFpLwd3e9Zp6WAPK/snDzF9Tb4KL+GB85n
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,11 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBfjCCASOgAwIBAgIBATAKBggqhkjOPQQDAjAiMSAwHgYDVQQDExdJbnZhbGlk
|
||||
IEV4dGVuc2lvbnMgUm9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAw
|
||||
MFowIjEgMB4GA1UEAxMXSW52YWxpZCBFeHRlbnNpb25zIFJvb3QwWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44TqChRYI6IeV9tI
|
||||
B6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolto0gwRjAOBgNVHQ8BAf8E
|
||||
BAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
|
||||
HQ4EB0lOVkFMSUQwCgYIKoZIzj0EAwIDSQAwRgIhAJbUNO8zfK439VpI2rrG9gTl
|
||||
fjunP2fKsz3EK8NUtS12AiEA1m9Uzb+sUTCGhAlGEsDkjFbp3SCbvbWn7YhzqJkR
|
||||
xvQ=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,184 @@
|
||||
/* Copyright (c) 2020, 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. */
|
||||
|
||||
// make_invalid_extensions.go generates a number of certificate chains with
|
||||
// invalid extension encodings.
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type extension struct {
|
||||
// The name of the extension, in a form suitable for including in a
|
||||
// filename.
|
||||
name string
|
||||
// The extension's OID.
|
||||
oid []int
|
||||
}
|
||||
|
||||
var extensions = []extension{
|
||||
{name: "authority_key_identifier", oid: []int{2, 5, 29, 35}},
|
||||
{name: "basic_constraints", oid: []int{2, 5, 29, 19}},
|
||||
{name: "ext_key_usage", oid: []int{2, 5, 29, 37}},
|
||||
{name: "key_usage", oid: []int{2, 5, 29, 15}},
|
||||
{name: "name_constraints", oid: []int{2, 5, 29, 30}},
|
||||
{name: "subject_alt_name", oid: []int{2, 5, 29, 17}},
|
||||
{name: "subject_key_identifier", oid: []int{2, 5, 29, 14}},
|
||||
}
|
||||
|
||||
var leafKey, intermediateKey, rootKey *ecdsa.PrivateKey
|
||||
|
||||
func init() {
|
||||
leafKey = ecdsaKeyFromPEMOrPanic(leafKeyPEM)
|
||||
intermediateKey = ecdsaKeyFromPEMOrPanic(intermediateKeyPEM)
|
||||
rootKey = ecdsaKeyFromPEMOrPanic(rootKeyPEM)
|
||||
}
|
||||
|
||||
type templateAndKey struct {
|
||||
template x509.Certificate
|
||||
key *ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
func generateCertificateOrPanic(path string, subject, issuer *templateAndKey) {
|
||||
cert, err := x509.CreateCertificate(rand.Reader, &subject.template, &issuer.template, &subject.key.PublicKey, issuer.key)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
file, err := os.Create(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
err = pem.Encode(file, &pem.Block{Type: "CERTIFICATE", Bytes: cert})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
notBefore, err := time.Parse(time.RFC3339, "2000-01-01T00:00:00Z")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
notAfter, err := time.Parse(time.RFC3339, "2100-01-01T00:00:00Z")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
root := templateAndKey{
|
||||
template: x509.Certificate{
|
||||
SerialNumber: new(big.Int).SetInt64(1),
|
||||
Subject: pkix.Name{CommonName: "Invalid Extensions Root"},
|
||||
NotBefore: notBefore,
|
||||
NotAfter: notAfter,
|
||||
BasicConstraintsValid: true,
|
||||
IsCA: true,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
KeyUsage: x509.KeyUsageCertSign,
|
||||
SignatureAlgorithm: x509.ECDSAWithSHA256,
|
||||
},
|
||||
key: rootKey,
|
||||
}
|
||||
intermediate := templateAndKey{
|
||||
template: x509.Certificate{
|
||||
SerialNumber: new(big.Int).SetInt64(2),
|
||||
Subject: pkix.Name{CommonName: "Invalid Extensions Intermediate"},
|
||||
NotBefore: notBefore,
|
||||
NotAfter: notAfter,
|
||||
BasicConstraintsValid: true,
|
||||
IsCA: true,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
KeyUsage: x509.KeyUsageCertSign,
|
||||
SignatureAlgorithm: x509.ECDSAWithSHA256,
|
||||
},
|
||||
key: intermediateKey,
|
||||
}
|
||||
leaf := templateAndKey{
|
||||
template: x509.Certificate{
|
||||
SerialNumber: new(big.Int).SetInt64(3),
|
||||
Subject: pkix.Name{CommonName: "www.example.com"},
|
||||
NotBefore: notBefore,
|
||||
NotAfter: notAfter,
|
||||
BasicConstraintsValid: true,
|
||||
IsCA: false,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
KeyUsage: x509.KeyUsageCertSign,
|
||||
SignatureAlgorithm: x509.ECDSAWithSHA256,
|
||||
DNSNames: []string{"www.example.com"},
|
||||
},
|
||||
key: leafKey,
|
||||
}
|
||||
|
||||
// Generate a valid certificate chain from the templates.
|
||||
generateCertificateOrPanic("invalid_extension_root.pem", &root, &root)
|
||||
generateCertificateOrPanic("invalid_extension_intermediate.pem", &intermediate, &root)
|
||||
generateCertificateOrPanic("invalid_extension_leaf.pem", &leaf, &intermediate)
|
||||
|
||||
// Make copies of each of the three certificates with invalid extensions.
|
||||
// These copies may be substituted into the valid chain.
|
||||
for _, ext := range extensions {
|
||||
invalidExtension := []pkix.Extension{{Id: ext.oid, Value: []byte("INVALID")}}
|
||||
|
||||
rootInvalid := root
|
||||
rootInvalid.template.ExtraExtensions = invalidExtension
|
||||
generateCertificateOrPanic(fmt.Sprintf("invalid_extension_root_%s.pem", ext.name), &rootInvalid, &rootInvalid)
|
||||
|
||||
intermediateInvalid := intermediate
|
||||
intermediateInvalid.template.ExtraExtensions = invalidExtension
|
||||
generateCertificateOrPanic(fmt.Sprintf("invalid_extension_intermediate_%s.pem", ext.name), &intermediateInvalid, &root)
|
||||
|
||||
leafInvalid := leaf
|
||||
leafInvalid.template.ExtraExtensions = invalidExtension
|
||||
generateCertificateOrPanic(fmt.Sprintf("invalid_extension_leaf_%s.pem", ext.name), &leafInvalid, &intermediate)
|
||||
}
|
||||
}
|
||||
|
||||
const leafKeyPEM = `-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgoPUXNXuH9mgiS/nk
|
||||
024SYxryxMa3CyGJldiHymLxSquhRANCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5
|
||||
w8u3SSwm7HZREvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5X
|
||||
-----END PRIVATE KEY-----`
|
||||
|
||||
const intermediateKeyPEM = `-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgWHKCKgY058ahE3t6
|
||||
vpxVQgzlycgCVMogwjK0y3XMNfWhRANCAATiOnyojN4xS5C8gJ/PHL5cOEsMbsoE
|
||||
Y6KT9xRQSh8lEL4d1Vb36kqUgkpqedEImo0Og4Owk6VWVVR/m4Lk+yUw
|
||||
-----END PRIVATE KEY-----`
|
||||
|
||||
const rootKeyPEM = `-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBwND/eHytW0I417J
|
||||
Hr+qcPlp5N1jM3ACXys57bPujg+hRANCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44Tq
|
||||
ChRYI6IeV9tIB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolt
|
||||
-----END PRIVATE KEY-----`
|
||||
|
||||
func ecdsaKeyFromPEMOrPanic(in string) *ecdsa.PrivateKey {
|
||||
keyBlock, _ := pem.Decode([]byte(in))
|
||||
if keyBlock == nil || keyBlock.Type != "PRIVATE KEY" {
|
||||
panic("could not decode private key")
|
||||
}
|
||||
key, err := x509.ParsePKCS8PrivateKey(keyBlock.Bytes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return key.(*ecdsa.PrivateKey)
|
||||
}
|
||||
@@ -65,73 +65,6 @@
|
||||
* it to avoid downstream churn. */
|
||||
OPENSSL_DECLARE_ERROR_REASON(X509, UNSUPPORTED_ALGORITHM)
|
||||
|
||||
int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version,
|
||||
int ptype, void *pval, uint8_t *penc, int penclen) {
|
||||
uint8_t **ppenc = NULL;
|
||||
if (version >= 0) {
|
||||
if (!ASN1_INTEGER_set(priv->version, version)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (penc) {
|
||||
int pmtype;
|
||||
ASN1_OCTET_STRING *oct;
|
||||
|
||||
oct = ASN1_OCTET_STRING_new();
|
||||
if (!oct) {
|
||||
return 0;
|
||||
}
|
||||
oct->data = penc;
|
||||
ppenc = &oct->data;
|
||||
oct->length = penclen;
|
||||
if (priv->broken == PKCS8_NO_OCTET) {
|
||||
pmtype = V_ASN1_SEQUENCE;
|
||||
} else {
|
||||
pmtype = V_ASN1_OCTET_STRING;
|
||||
}
|
||||
ASN1_TYPE_set(priv->pkey, pmtype, oct);
|
||||
}
|
||||
|
||||
if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) {
|
||||
/* If call fails do not swallow 'enc' */
|
||||
if (ppenc) {
|
||||
*ppenc = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, const uint8_t **pk, int *ppklen,
|
||||
X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8) {
|
||||
if (ppkalg) {
|
||||
*ppkalg = p8->pkeyalg->algorithm;
|
||||
}
|
||||
|
||||
if (p8->pkey->type == V_ASN1_OCTET_STRING) {
|
||||
p8->broken = PKCS8_OK;
|
||||
if (pk) {
|
||||
*pk = p8->pkey->value.octet_string->data;
|
||||
*ppklen = p8->pkey->value.octet_string->length;
|
||||
}
|
||||
} else if (p8->pkey->type == V_ASN1_SEQUENCE) {
|
||||
p8->broken = PKCS8_NO_OCTET;
|
||||
if (pk) {
|
||||
*pk = p8->pkey->value.sequence->data;
|
||||
*ppklen = p8->pkey->value.sequence->length;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pa) {
|
||||
*pa = p8->pkeyalg;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent) {
|
||||
const uint8_t *s;
|
||||
int i, n;
|
||||
|
||||
+12
-5
@@ -67,6 +67,7 @@
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "../x509v3/internal.h"
|
||||
|
||||
|
||||
int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
|
||||
@@ -175,12 +176,18 @@ unsigned long X509_subject_name_hash_old(X509 *x)
|
||||
*/
|
||||
int X509_cmp(const X509 *a, const X509 *b)
|
||||
{
|
||||
int rv;
|
||||
/* ensure hash is valid */
|
||||
X509_check_purpose((X509 *)a, -1, 0);
|
||||
X509_check_purpose((X509 *)b, -1, 0);
|
||||
/* Fill in the |sha1_hash| fields.
|
||||
*
|
||||
* TODO(davidben): This may fail, in which case the the hash will be all
|
||||
* zeros. This produces a consistent comparison (failures are sticky), but
|
||||
* not a good one. OpenSSL now returns -2, but this is not a consistent
|
||||
* comparison and may cause misbehaving sorts by transitivity. For now, we
|
||||
* retain the old OpenSSL behavior, which was to ignore the error. See
|
||||
* https://crbug.com/boringssl/355. */
|
||||
x509v3_cache_extensions((X509 *)a);
|
||||
x509v3_cache_extensions((X509 *)b);
|
||||
|
||||
rv = OPENSSL_memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
|
||||
int rv = OPENSSL_memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
|
||||
if (rv)
|
||||
return rv;
|
||||
/* Check for match against stored encoding too */
|
||||
|
||||
@@ -107,6 +107,16 @@ X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
long X509_REQ_get_version(const X509_REQ *req)
|
||||
{
|
||||
return ASN1_INTEGER_get(req->req_info->version);
|
||||
}
|
||||
|
||||
X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req)
|
||||
{
|
||||
return req->req_info->subject;
|
||||
}
|
||||
|
||||
EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req)
|
||||
{
|
||||
if ((req == NULL) || (req->req_info == NULL))
|
||||
|
||||
@@ -60,6 +60,16 @@
|
||||
#include <openssl/obj.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
long X509_get_version(const X509 *x509)
|
||||
{
|
||||
return ASN1_INTEGER_get(x509->cert_info->version);
|
||||
}
|
||||
|
||||
X509_CINF *X509_get_cert_info(const X509 *x509)
|
||||
{
|
||||
return x509->cert_info;
|
||||
}
|
||||
|
||||
int X509_set_version(X509 *x, long version)
|
||||
{
|
||||
if (x == NULL)
|
||||
@@ -137,6 +147,14 @@ ASN1_TIME *X509_getm_notBefore(X509 *x)
|
||||
return x->cert_info->validity->notBefore;
|
||||
}
|
||||
|
||||
ASN1_TIME *X509_get_notBefore(const X509 *x509)
|
||||
{
|
||||
// In OpenSSL, this function is an alias for |X509_getm_notBefore|, but our
|
||||
// |X509_getm_notBefore| is const-correct. |X509_get_notBefore| was
|
||||
// originally a macro, so it needs to capture both get0 and getm use cases.
|
||||
return x509->cert_info->validity->notBefore;
|
||||
}
|
||||
|
||||
int X509_set_notAfter(X509 *x, const ASN1_TIME *tm)
|
||||
{
|
||||
ASN1_TIME *in;
|
||||
@@ -167,6 +185,14 @@ ASN1_TIME *X509_getm_notAfter(X509 *x)
|
||||
return x->cert_info->validity->notAfter;
|
||||
}
|
||||
|
||||
ASN1_TIME *X509_get_notAfter(const X509 *x509)
|
||||
{
|
||||
// In OpenSSL, this function is an alias for |X509_getm_notAfter|, but our
|
||||
// |X509_getm_notAfter| is const-correct. |X509_get_notAfter| was
|
||||
// originally a macro, so it needs to capture both get0 and getm use cases.
|
||||
return x509->cert_info->validity->notAfter;
|
||||
}
|
||||
|
||||
int X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
|
||||
{
|
||||
if ((x == NULL) || (x->cert_info == NULL))
|
||||
@@ -183,3 +209,18 @@ const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x)
|
||||
{
|
||||
return x->cert_info->signature;
|
||||
}
|
||||
|
||||
void X509_CINF_set_modified(X509_CINF *cinf)
|
||||
{
|
||||
cinf->enc.modified = 1;
|
||||
}
|
||||
|
||||
const X509_ALGOR *X509_CINF_get_signature(const X509_CINF *cinf)
|
||||
{
|
||||
return cinf->signature;
|
||||
}
|
||||
|
||||
X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x509)
|
||||
{
|
||||
return x509->cert_info->key;
|
||||
}
|
||||
|
||||
+361
-26
@@ -233,6 +233,13 @@ static const char kRSAKey[] =
|
||||
"moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
|
||||
"-----END RSA PRIVATE KEY-----\n";
|
||||
|
||||
static const char kP256Key[] =
|
||||
"-----BEGIN PRIVATE KEY-----\n"
|
||||
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
|
||||
"TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
|
||||
"Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
|
||||
"-----END PRIVATE KEY-----\n";
|
||||
|
||||
// kCRLTestRoot is a test root certificate. It has private key:
|
||||
//
|
||||
// -----BEGIN RSA PRIVATE KEY-----
|
||||
@@ -354,16 +361,16 @@ static const char kBadIssuerCRL[] =
|
||||
// extension.
|
||||
static const char kKnownCriticalCRL[] =
|
||||
"-----BEGIN X509 CRL-----\n"
|
||||
"MIIBujCBowIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"MIIBuDCBoQIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJ\n"
|
||||
"Qm9yaW5nU1NMFw0xNjA5MjYxNTEwNTVaFw0xNjEwMjYxNTEwNTVaoCEwHzAKBgNV\n"
|
||||
"HRQEAwIBATARBgNVHRwBAf8EBzAFoQMBAf8wDQYJKoZIhvcNAQELBQADggEBAA+3\n"
|
||||
"i+5e5Ub8sccfgOBs6WVJFI9c8gvJjrJ8/dYfFIAuCyeocs7DFXn1n13CRZ+URR/Q\n"
|
||||
"mVWgU28+xeusuSPYFpd9cyYTcVyNUGNTI3lwgcE/yVjPaOmzSZKdPakApRxtpKKQ\n"
|
||||
"NN/56aQz3bnT/ZSHQNciRB8U6jiD9V30t0w+FDTpGaG+7bzzUH3UVF9xf9Ctp60A\n"
|
||||
"3mfLe0scas7owSt4AEFuj2SPvcE7yvdOXbu+IEv21cEJUVExJAbhvIweHXh6yRW+\n"
|
||||
"7VVeiNzdIjkZjyTmAzoXGha4+wbxXyBRbfH+XWcO/H+8nwyG8Gktdu2QB9S9nnIp\n"
|
||||
"o/1TpfOMSGhMyMoyPrk=\n"
|
||||
"Qm9yaW5nU1NMFw0xNjA5MjYxNTEwNTVaFw0xNjEwMjYxNTEwNTVaoB8wHTAKBgNV\n"
|
||||
"HRQEAwIBATAPBgNVHRwBAf8EBTADgQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAs37Jq\n"
|
||||
"3Htcehm6C2PKXOHekwTqTLOPWsYHfF68kYhdzcopDZBeoKE7jLRkRRGFDaR/tfUs\n"
|
||||
"kwLSDNSQ8EwPb9PT1X8kmFn9QmJgWD6f6BzaH5ZZ9iBUwOcvrydlb/jnjdIZHQxs\n"
|
||||
"fKOAceW5XX3f7DANC3qwYLsQZR/APkfV8nXjPYVUz1kKj04uq/BbQviInjyUYixN\n"
|
||||
"xDx+GDWVVXccehcwAu983kAqP+JDaVQPBVksLuBXz2adrEWwvbLCnZeL3zH1IY9h\n"
|
||||
"6MFO6echpvGbU/H+dRX9UkhdJ7gdwKVD3RjfJl+DRVox9lz8Pbo5H699Tkv9/DQP\n"
|
||||
"9dMWxqhQlv23osLp\n"
|
||||
"-----END X509 CRL-----\n";
|
||||
|
||||
// kUnknownCriticalCRL is kBasicCRL but with an unknown critical extension.
|
||||
@@ -385,16 +392,32 @@ static const char kUnknownCriticalCRL[] =
|
||||
// point extension followed by an unknown critical extension
|
||||
static const char kUnknownCriticalCRL2[] =
|
||||
"-----BEGIN X509 CRL-----\n"
|
||||
"MIIBzzCBuAIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"MIIBzTCBtgIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJ\n"
|
||||
"Qm9yaW5nU1NMFw0xNjA5MjYxNTEwNTVaFw0xNjEwMjYxNTEwNTVaoDYwNDAKBgNV\n"
|
||||
"HRQEAwIBATARBgNVHRwBAf8EBzAFoQMBAf8wEwYMKoZIhvcSBAGEtwkAAQH/BAAw\n"
|
||||
"DQYJKoZIhvcNAQELBQADggEBACTcpQC8jXL12JN5YzOcQ64ubQIe0XxRAd30p7qB\n"
|
||||
"BTXGpgqBjrjxRfLms7EBYodEXB2oXMsDq3km0vT1MfYdsDD05S+SQ9CDsq/pUfaC\n"
|
||||
"E2WNI5p8WircRnroYvbN2vkjlRbMd1+yNITohXYXCJwjEOAWOx3XIM10bwPYBv4R\n"
|
||||
"rDobuLHoMgL3yHgMHmAkP7YpkBucNqeBV8cCdeAZLuhXFWi6yfr3r/X18yWbC/r2\n"
|
||||
"2xXdkrSqXLFo7ToyP8YKTgiXpya4x6m53biEYwa2ULlas0igL6DK7wjYZX95Uy7H\n"
|
||||
"GKljn9weIYiMPV/BzGymwfv2EW0preLwtyJNJPaxbdin6Jc=\n"
|
||||
"Qm9yaW5nU1NMFw0xNjA5MjYxNTEwNTVaFw0xNjEwMjYxNTEwNTVaoDQwMjAKBgNV\n"
|
||||
"HRQEAwIBATAPBgNVHRwBAf8EBTADgQH/MBMGDCqGSIb3EgQBhLcJAAEB/wQAMA0G\n"
|
||||
"CSqGSIb3DQEBCwUAA4IBAQBgSogsC5kf2wzr+0hmZtmLXYd0itAiYO0Gh9AyaEOO\n"
|
||||
"myJFuqICHBSLXXUgwNkTUa2x2I/ivyReVFV756VOlWoaV2wJUs0zeCeVBgC9ZFsq\n"
|
||||
"5a+8OGgXwgoYESFV5Y3QRF2a1Ytzfbw/o6xLXzTngvMsLOs12D4B5SkopyEZibF4\n"
|
||||
"tXlRZyvEudTg3CCrjNP+p/GV07nZ3wcMmKJwQeilgzFUV7NaVCCo9jvPBGp0RxAN\n"
|
||||
"KNif7jmjK4hD5mswo/Eq5kxQIc+mTfuUFdgHuAu1hfLYe0YK+Hr4RFf6Qy4hl7Ne\n"
|
||||
"YjqkkSVIcr87u+8AznwdstnQzsyD27Jt7SjVORkYRywi\n"
|
||||
"-----END X509 CRL-----\n";
|
||||
|
||||
// kBadExtensionCRL is kBasicCRL but with an incorrectly-encoded issuing
|
||||
// distribution point extension.
|
||||
static const char kBadExtensionCRL[] =
|
||||
"-----BEGIN X509 CRL-----\n"
|
||||
"MIIBujCBowIBATANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzETMBEGA1UE\n"
|
||||
"CAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzESMBAGA1UECgwJ\n"
|
||||
"Qm9yaW5nU1NMFw0xNjA5MjYxNTEwNTVaFw0xNjEwMjYxNTEwNTVaoCEwHzAKBgNV\n"
|
||||
"HRQEAwIBATARBgNVHRwBAf8EBzAFoQMBAf8wDQYJKoZIhvcNAQELBQADggEBAA+3\n"
|
||||
"i+5e5Ub8sccfgOBs6WVJFI9c8gvJjrJ8/dYfFIAuCyeocs7DFXn1n13CRZ+URR/Q\n"
|
||||
"mVWgU28+xeusuSPYFpd9cyYTcVyNUGNTI3lwgcE/yVjPaOmzSZKdPakApRxtpKKQ\n"
|
||||
"NN/56aQz3bnT/ZSHQNciRB8U6jiD9V30t0w+FDTpGaG+7bzzUH3UVF9xf9Ctp60A\n"
|
||||
"3mfLe0scas7owSt4AEFuj2SPvcE7yvdOXbu+IEv21cEJUVExJAbhvIweHXh6yRW+\n"
|
||||
"7VVeiNzdIjkZjyTmAzoXGha4+wbxXyBRbfH+XWcO/H+8nwyG8Gktdu2QB9S9nnIp\n"
|
||||
"o/1TpfOMSGhMyMoyPrk=\n"
|
||||
"-----END X509 CRL-----\n";
|
||||
|
||||
// kEd25519Cert is a self-signed Ed25519 certificate.
|
||||
@@ -1314,29 +1337,32 @@ TEST(X509Test, TestCRL) {
|
||||
ASSERT_EQ(X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION,
|
||||
Verify(leaf.get(), {root.get()}, {root.get()},
|
||||
{unknown_critical_crl2.get()}, X509_V_FLAG_CRL_CHECK));
|
||||
|
||||
// Parsing kBadExtensionCRL should fail.
|
||||
EXPECT_FALSE(CRLFromPEM(kBadExtensionCRL));
|
||||
}
|
||||
|
||||
TEST(X509Test, ManyNamesAndConstraints) {
|
||||
bssl::UniquePtr<X509> many_constraints(
|
||||
CertFromPEM(GetTestData("crypto/x509/many_constraints.pem").c_str()));
|
||||
bssl::UniquePtr<X509> many_constraints(CertFromPEM(
|
||||
GetTestData("crypto/x509/test/many_constraints.pem").c_str()));
|
||||
ASSERT_TRUE(many_constraints);
|
||||
bssl::UniquePtr<X509> many_names1(
|
||||
CertFromPEM(GetTestData("crypto/x509/many_names1.pem").c_str()));
|
||||
CertFromPEM(GetTestData("crypto/x509/test/many_names1.pem").c_str()));
|
||||
ASSERT_TRUE(many_names1);
|
||||
bssl::UniquePtr<X509> many_names2(
|
||||
CertFromPEM(GetTestData("crypto/x509/many_names2.pem").c_str()));
|
||||
CertFromPEM(GetTestData("crypto/x509/test/many_names2.pem").c_str()));
|
||||
ASSERT_TRUE(many_names2);
|
||||
bssl::UniquePtr<X509> many_names3(
|
||||
CertFromPEM(GetTestData("crypto/x509/many_names3.pem").c_str()));
|
||||
CertFromPEM(GetTestData("crypto/x509/test/many_names3.pem").c_str()));
|
||||
ASSERT_TRUE(many_names3);
|
||||
bssl::UniquePtr<X509> some_names1(
|
||||
CertFromPEM(GetTestData("crypto/x509/some_names1.pem").c_str()));
|
||||
CertFromPEM(GetTestData("crypto/x509/test/some_names1.pem").c_str()));
|
||||
ASSERT_TRUE(some_names1);
|
||||
bssl::UniquePtr<X509> some_names2(
|
||||
CertFromPEM(GetTestData("crypto/x509/some_names2.pem").c_str()));
|
||||
CertFromPEM(GetTestData("crypto/x509/test/some_names2.pem").c_str()));
|
||||
ASSERT_TRUE(some_names2);
|
||||
bssl::UniquePtr<X509> some_names3(
|
||||
CertFromPEM(GetTestData("crypto/x509/some_names3.pem").c_str()));
|
||||
CertFromPEM(GetTestData("crypto/x509/test/some_names3.pem").c_str()));
|
||||
ASSERT_TRUE(some_names3);
|
||||
|
||||
EXPECT_EQ(X509_V_ERR_UNSPECIFIED,
|
||||
@@ -2226,3 +2252,312 @@ TEST(X509Test, ServerGatedCryptoEKUs) {
|
||||
EXPECT_EQ(X509_V_OK, verify_cert(leaf));
|
||||
}
|
||||
}
|
||||
|
||||
// Test that invalid extensions are rejected by, if not the parser, at least the
|
||||
// verifier.
|
||||
TEST(X509Test, InvalidExtensions) {
|
||||
bssl::UniquePtr<X509> root = CertFromPEM(
|
||||
GetTestData("crypto/x509/test/invalid_extension_root.pem").c_str());
|
||||
ASSERT_TRUE(root);
|
||||
bssl::UniquePtr<X509> intermediate = CertFromPEM(
|
||||
GetTestData("crypto/x509/test/invalid_extension_intermediate.pem")
|
||||
.c_str());
|
||||
ASSERT_TRUE(intermediate);
|
||||
bssl::UniquePtr<X509> leaf = CertFromPEM(
|
||||
GetTestData("crypto/x509/test/invalid_extension_leaf.pem").c_str());
|
||||
ASSERT_TRUE(leaf);
|
||||
|
||||
// Sanity-check that the baseline chain is accepted.
|
||||
EXPECT_EQ(X509_V_OK,
|
||||
Verify(leaf.get(), {root.get()}, {intermediate.get()}, {}));
|
||||
|
||||
static const char *kExtensions[] = {
|
||||
"authority_key_identifier",
|
||||
"basic_constraints",
|
||||
"ext_key_usage",
|
||||
"key_usage",
|
||||
"name_constraints",
|
||||
"subject_alt_name",
|
||||
"subject_key_identifier",
|
||||
};
|
||||
for (const char *ext : kExtensions) {
|
||||
SCOPED_TRACE(ext);
|
||||
bssl::UniquePtr<X509> invalid_root = CertFromPEM(
|
||||
GetTestData((std::string("crypto/x509/test/invalid_extension_root_") +
|
||||
ext + ".pem")
|
||||
.c_str())
|
||||
.c_str());
|
||||
ASSERT_TRUE(invalid_root);
|
||||
|
||||
bssl::UniquePtr<X509> invalid_intermediate = CertFromPEM(
|
||||
GetTestData(
|
||||
(std::string("crypto/x509/test/invalid_extension_intermediate_") +
|
||||
ext + ".pem")
|
||||
.c_str())
|
||||
.c_str());
|
||||
ASSERT_TRUE(invalid_intermediate);
|
||||
|
||||
bssl::UniquePtr<X509> invalid_leaf = CertFromPEM(
|
||||
GetTestData((std::string("crypto/x509/test/invalid_extension_leaf_") +
|
||||
ext + ".pem")
|
||||
.c_str())
|
||||
.c_str());
|
||||
ASSERT_TRUE(invalid_leaf);
|
||||
|
||||
EXPECT_EQ(
|
||||
X509_V_ERR_INVALID_EXTENSION,
|
||||
Verify(invalid_leaf.get(), {root.get()}, {intermediate.get()}, {}));
|
||||
|
||||
// If the invalid extension is on an intermediate or root,
|
||||
// |X509_verify_cert| notices by way of being unable to build a path to
|
||||
// a valid issuer.
|
||||
EXPECT_EQ(
|
||||
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
|
||||
Verify(leaf.get(), {root.get()}, {invalid_intermediate.get()}, {}));
|
||||
EXPECT_EQ(
|
||||
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
|
||||
Verify(leaf.get(), {invalid_root.get()}, {intermediate.get()}, {}));
|
||||
}
|
||||
}
|
||||
|
||||
// kExplicitDefaultVersionPEM is an X.509v1 certificate with the version number
|
||||
// encoded explicitly, rather than omitted as required by DER.
|
||||
static const char kExplicitDefaultVersionPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBfTCCASSgAwIBAAIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
|
||||
"QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
|
||||
"dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
|
||||
"BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
|
||||
"dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
|
||||
"v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
|
||||
"HPUdfvGULUvPciLBMAkGByqGSM49BAEDSAAwRQIhAPKgNV5ROjbDgnmb7idQhY5w\n"
|
||||
"BnSVV9IpdAD0vhWHXcQHAiB8HnkUaiGD8Hp0aHlfFJmaaLTxy54VXuYfMlJhXnXJ\n"
|
||||
"FA==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// kNegativeVersionPEM is an X.509 certificate with a negative version number.
|
||||
static const char kNegativeVersionPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBfTCCASSgAwIB/wIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
|
||||
"QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
|
||||
"dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
|
||||
"BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
|
||||
"dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
|
||||
"v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
|
||||
"HPUdfvGULUvPciLBMAkGByqGSM49BAEDSAAwRQIhAPKgNV5ROjbDgnmb7idQhY5w\n"
|
||||
"BnSVV9IpdAD0vhWHXcQHAiB8HnkUaiGD8Hp0aHlfFJmaaLTxy54VXuYfMlJhXnXJ\n"
|
||||
"FA==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// kFutureVersionPEM is an X.509 certificate with a version number value of
|
||||
// three, which is not defined. (v3 has value two).
|
||||
static const char kFutureVersionPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBfTCCASSgAwIBAwIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
|
||||
"QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
|
||||
"dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
|
||||
"BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
|
||||
"dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
|
||||
"v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
|
||||
"HPUdfvGULUvPciLBMAkGByqGSM49BAEDSAAwRQIhAPKgNV5ROjbDgnmb7idQhY5w\n"
|
||||
"BnSVV9IpdAD0vhWHXcQHAiB8HnkUaiGD8Hp0aHlfFJmaaLTxy54VXuYfMlJhXnXJ\n"
|
||||
"FA==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// kOverflowVersionPEM is an X.509 certificate with a version field which
|
||||
// overflows |uint64_t|.
|
||||
static const char kOverflowVersionPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBoDCCAUegJgIkAP//////////////////////////////////////////////\n"
|
||||
"AgkA2UwE2kl9v+swCQYHKoZIzj0EATBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwK\n"
|
||||
"U29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMB4X\n"
|
||||
"DTE0MDQyMzIzMjE1N1oXDTE0MDUyMzIzMjE1N1owRTELMAkGA1UEBhMCQVUxEzAR\n"
|
||||
"BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5\n"
|
||||
"IEx0ZDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOYraeK/ZZ+Xvi8eDZSKTNWX\n"
|
||||
"a7epHg1G+92pqR6d3LpaAefWl6gKGPnDxKMeVuJ8g0jbFhoc9R1+8ZQtS89yIsEw\n"
|
||||
"CQYHKoZIzj0EAQNIADBFAiEA8qA1XlE6NsOCeZvuJ1CFjnAGdJVX0il0APS+FYdd\n"
|
||||
"xAcCIHweeRRqIYPwenRoeV8UmZpotPHLnhVe5h8yUmFedckU\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// kV1WithExtensionsPEM is an X.509v1 certificate with extensions.
|
||||
static const char kV1WithExtensionsPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIByjCCAXECCQDZTATaSX2/6zAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw\n"
|
||||
"EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0\n"
|
||||
"eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQswCQYDVQQG\n"
|
||||
"EwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lk\n"
|
||||
"Z2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp4r9ln5e+\n"
|
||||
"Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsWGhz1HX7x\n"
|
||||
"lC1Lz3IiwaNQME4wHQYDVR0OBBYEFKuE0qyrlfCCThZ4B1VXX+QmjYLRMB8GA1Ud\n"
|
||||
"IwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMAwGA1UdEwQFMAMBAf8wCQYHKoZI\n"
|
||||
"zj0EAQNIADBFAiEA8qA1XlE6NsOCeZvuJ1CFjnAGdJVX0il0APS+FYddxAcCIHwe\n"
|
||||
"eRRqIYPwenRoeV8UmZpotPHLnhVe5h8yUmFedckU\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// kV2WithExtensionsPEM is an X.509v2 certificate with extensions.
|
||||
static const char kV2WithExtensionsPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBzzCCAXagAwIBAQIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
|
||||
"QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
|
||||
"dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
|
||||
"BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
|
||||
"dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
|
||||
"v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
|
||||
"HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
|
||||
"HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
|
||||
"BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
|
||||
"BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// kV1WithIssuerUniqueIDPEM is an X.509v1 certificate with an issuerUniqueID.
|
||||
static const char kV1WithIssuerUniqueIDPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBgzCCASoCCQDZTATaSX2/6zAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw\n"
|
||||
"EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0\n"
|
||||
"eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQswCQYDVQQG\n"
|
||||
"EwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lk\n"
|
||||
"Z2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp4r9ln5e+\n"
|
||||
"Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsWGhz1HX7x\n"
|
||||
"lC1Lz3IiwYEJAAEjRWeJq83vMAkGByqGSM49BAEDSAAwRQIhAPKgNV5ROjbDgnmb\n"
|
||||
"7idQhY5wBnSVV9IpdAD0vhWHXcQHAiB8HnkUaiGD8Hp0aHlfFJmaaLTxy54VXuYf\n"
|
||||
"MlJhXnXJFA==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// kV1WithSubjectUniqueIDPEM is an X.509v1 certificate with an issuerUniqueID.
|
||||
static const char kV1WithSubjectUniqueIDPEM[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBgzCCASoCCQDZTATaSX2/6zAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw\n"
|
||||
"EQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0\n"
|
||||
"eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQswCQYDVQQG\n"
|
||||
"EwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lk\n"
|
||||
"Z2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp4r9ln5e+\n"
|
||||
"Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsWGhz1HX7x\n"
|
||||
"lC1Lz3IiwYIJAAEjRWeJq83vMAkGByqGSM49BAEDSAAwRQIhAPKgNV5ROjbDgnmb\n"
|
||||
"7idQhY5wBnSVV9IpdAD0vhWHXcQHAiB8HnkUaiGD8Hp0aHlfFJmaaLTxy54VXuYf\n"
|
||||
"MlJhXnXJFA==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
// Test that the X.509 parser enforces versions are valid and match the fields
|
||||
// present.
|
||||
TEST(X509Test, InvalidVersion) {
|
||||
// kExplicitDefaultVersionPEM is invalid but, for now, we accept it. See
|
||||
// https://crbug.com/boringssl/364.
|
||||
EXPECT_TRUE(CertFromPEM(kExplicitDefaultVersionPEM));
|
||||
|
||||
EXPECT_FALSE(CertFromPEM(kNegativeVersionPEM));
|
||||
EXPECT_FALSE(CertFromPEM(kFutureVersionPEM));
|
||||
EXPECT_FALSE(CertFromPEM(kOverflowVersionPEM));
|
||||
EXPECT_FALSE(CertFromPEM(kV1WithExtensionsPEM));
|
||||
EXPECT_FALSE(CertFromPEM(kV2WithExtensionsPEM));
|
||||
EXPECT_FALSE(CertFromPEM(kV1WithIssuerUniqueIDPEM));
|
||||
EXPECT_FALSE(CertFromPEM(kV1WithSubjectUniqueIDPEM));
|
||||
}
|
||||
|
||||
// The following strings are test certificates signed by kP256Key and kRSAKey,
|
||||
// with missing, NULL, or invalid algorithm parameters.
|
||||
static const char kP256NoParam[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBIDCBxqADAgECAgIE0jAKBggqhkjOPQQDAjAPMQ0wCwYDVQQDEwRUZXN0MCAX\n"
|
||||
"DTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAPMQ0wCwYDVQQDEwRUZXN0\n"
|
||||
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp4r9ln5e+Lx4NlIpM1Zdrt6ke\n"
|
||||
"DUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsWGhz1HX7xlC1Lz3IiwaMQMA4w\n"
|
||||
"DAYDVR0TBAUwAwEB/zAKBggqhkjOPQQDAgNJADBGAiEAqdIiF+bN9Cl44oUeICpy\n"
|
||||
"aXd7HqhpVUaglYKw9ChmNUACIQCpMdL0fNkFNDbRww9dSl/y7kBdk/tp16HiqeSy\n"
|
||||
"gGzFYg==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
static const char kP256NullParam[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBJDCByKADAgECAgIE0jAMBggqhkjOPQQDAgUAMA8xDTALBgNVBAMTBFRlc3Qw\n"
|
||||
"IBcNMDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMA8xDTALBgNVBAMTBFRl\n"
|
||||
"c3QwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2niv2Wfl74vHg2UikzVl2u3\n"
|
||||
"qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLBoxAw\n"
|
||||
"DjAMBgNVHRMEBTADAQH/MAwGCCqGSM49BAMCBQADSQAwRgIhAKILHmyo+F3Cn/VX\n"
|
||||
"UUeSXOQQKX5aLzsQitwwmNF3ZgH3AiEAsYHcrVj/ftmoQIORARkQ/+PrqntXev8r\n"
|
||||
"t6uPxHrmpUY=\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
static const char kP256InvalidParam[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBMTCBz6ADAgECAgIE0jATBggqhkjOPQQDAgQHZ2FyYmFnZTAPMQ0wCwYDVQQD\n"
|
||||
"EwRUZXN0MCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAPMQ0wCwYD\n"
|
||||
"VQQDEwRUZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp4r9ln5e+Lx4N\n"
|
||||
"lIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsWGhz1HX7xlC1L\n"
|
||||
"z3IiwaMQMA4wDAYDVR0TBAUwAwEB/zATBggqhkjOPQQDAgQHZ2FyYmFnZQNIADBF\n"
|
||||
"AiAglpDf/YhN89LeJ2WAs/F0SJIrsuhS4uoInIz6WXUiuQIhAIu5Pwhp5E3Pbo8y\n"
|
||||
"fLULTZnynuQUULQkRcF7S7T2WpIL\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
static const char kRSANoParam[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBWzCBx6ADAgECAgIE0jALBgkqhkiG9w0BAQswDzENMAsGA1UEAxMEVGVzdDAg\n"
|
||||
"Fw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowDzENMAsGA1UEAxMEVGVz\n"
|
||||
"dDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOYraeK/ZZ+Xvi8eDZSKTNWXa7ep\n"
|
||||
"Hg1G+92pqR6d3LpaAefWl6gKGPnDxKMeVuJ8g0jbFhoc9R1+8ZQtS89yIsGjEDAO\n"
|
||||
"MAwGA1UdEwQFMAMBAf8wCwYJKoZIhvcNAQELA4GBAC1f8W3W0Ao7CPfIBQYDSbPh\n"
|
||||
"brZpbxdBU5x27JOS7iSa+Lc9pEH5VCX9vIypHVHXLPEfZ38yIt11eiyrmZB6w62N\n"
|
||||
"l9kIeZ6FVPmC30d3sXx70Jjs+ZX9yt7kD1gLyNAQQfeYfa4rORAZT1n2YitD74NY\n"
|
||||
"TWUH2ieFP3l+ecj1SeQR\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
static const char kRSANullParam[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBXzCByaADAgECAgIE0jANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDEwRUZXN0\n"
|
||||
"MCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAPMQ0wCwYDVQQDEwRU\n"
|
||||
"ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp4r9ln5e+Lx4NlIpM1Zdr\n"
|
||||
"t6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsWGhz1HX7xlC1Lz3IiwaMQ\n"
|
||||
"MA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQAzVcfIv+Rq1KrMXqIL\n"
|
||||
"fPq/cWZjgqFZA1RGaGElNaqp+rkJfamq5tDGzckWpebrK+jjRN7yIlcWDtPpy3Gy\n"
|
||||
"seZfvtBDR0TwJm0S/pQl8prKB4wgALcwe3bmi56Rq85nzY5ZLNcP16LQxL+jAAua\n"
|
||||
"SwmQUz4bRpckRBj+sIyp1We+pg==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
static const char kRSAInvalidParam[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIBbTCB0KADAgECAgIE0jAUBgkqhkiG9w0BAQsEB2dhcmJhZ2UwDzENMAsGA1UE\n"
|
||||
"AxMEVGVzdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowDzENMAsG\n"
|
||||
"A1UEAxMEVGVzdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOYraeK/ZZ+Xvi8e\n"
|
||||
"DZSKTNWXa7epHg1G+92pqR6d3LpaAefWl6gKGPnDxKMeVuJ8g0jbFhoc9R1+8ZQt\n"
|
||||
"S89yIsGjEDAOMAwGA1UdEwQFMAMBAf8wFAYJKoZIhvcNAQELBAdnYXJiYWdlA4GB\n"
|
||||
"AHTJ6cWWjCNrZhqiWWVI3jdK+h5xpRG8jGMXxR4JnjtoYRRusJLOXhmapwCB6fA0\n"
|
||||
"4vc+66O27v36yDmQX+tIc/hDrTpKNJptU8q3n2VagREvoHhkOTYkcCeS8vmnMtn8\n"
|
||||
"5OMNZ/ajVwOssw61GcAlScRqEHkZFBoGp7e+QpgB2tf9\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
TEST(X509Test, AlgorithmParameters) {
|
||||
// P-256 requires the parameter be omitted.
|
||||
bssl::UniquePtr<EVP_PKEY> key = PrivateKeyFromPEM(kP256Key);
|
||||
ASSERT_TRUE(key);
|
||||
|
||||
bssl::UniquePtr<X509> cert = CertFromPEM(kP256NoParam);
|
||||
ASSERT_TRUE(cert);
|
||||
EXPECT_TRUE(X509_verify(cert.get(), key.get()));
|
||||
|
||||
cert = CertFromPEM(kP256NullParam);
|
||||
ASSERT_TRUE(cert);
|
||||
EXPECT_FALSE(X509_verify(cert.get(), key.get()));
|
||||
uint32_t err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_X509, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(X509_R_INVALID_PARAMETER, ERR_GET_REASON(err));
|
||||
|
||||
cert = CertFromPEM(kP256InvalidParam);
|
||||
ASSERT_TRUE(cert);
|
||||
EXPECT_FALSE(X509_verify(cert.get(), key.get()));
|
||||
err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_X509, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(X509_R_INVALID_PARAMETER, ERR_GET_REASON(err));
|
||||
|
||||
// RSA parameters should be NULL, but we accept omitted ones.
|
||||
key = PrivateKeyFromPEM(kRSAKey);
|
||||
ASSERT_TRUE(key);
|
||||
|
||||
cert = CertFromPEM(kRSANoParam);
|
||||
ASSERT_TRUE(cert);
|
||||
EXPECT_TRUE(X509_verify(cert.get(), key.get()));
|
||||
|
||||
cert = CertFromPEM(kRSANullParam);
|
||||
ASSERT_TRUE(cert);
|
||||
EXPECT_TRUE(X509_verify(cert.get(), key.get()));
|
||||
|
||||
cert = CertFromPEM(kRSAInvalidParam);
|
||||
ASSERT_TRUE(cert);
|
||||
EXPECT_FALSE(X509_verify(cert.get(), key.get()));
|
||||
err = ERR_get_error();
|
||||
EXPECT_EQ(ERR_LIB_X509, ERR_GET_LIB(err));
|
||||
EXPECT_EQ(X509_R_INVALID_PARAMETER, ERR_GET_REASON(err));
|
||||
}
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
#include <openssl/obj.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "../x509v3/internal.h"
|
||||
|
||||
static int tr_cmp(const X509_TRUST **a, const X509_TRUST **b);
|
||||
static void trtable_free(X509_TRUST *p);
|
||||
|
||||
@@ -293,7 +295,8 @@ static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
|
||||
|
||||
static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
|
||||
{
|
||||
X509_check_purpose(x, -1, 0);
|
||||
if (!x509v3_cache_extensions(x))
|
||||
return X509_TRUST_UNTRUSTED;
|
||||
if (x->ex_flags & EXFLAG_SS)
|
||||
return X509_TRUST_TRUSTED;
|
||||
else
|
||||
|
||||
+28
-9
@@ -146,14 +146,16 @@ static int null_callback(int ok, X509_STORE_CTX *e)
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* Return 1 is a certificate is self signed */
|
||||
static int cert_self_signed(X509 *x)
|
||||
/* cert_self_signed checks if |x| is self-signed. If |x| is valid, it returns
|
||||
* one and sets |*out_is_self_signed| to the result. If |x| is invalid, it
|
||||
* returns zero. */
|
||||
static int cert_self_signed(X509 *x, int *out_is_self_signed)
|
||||
{
|
||||
X509_check_purpose(x, -1, 0);
|
||||
if (x->ex_flags & EXFLAG_SS)
|
||||
return 1;
|
||||
else
|
||||
if (!x509v3_cache_extensions(x)) {
|
||||
return 0;
|
||||
}
|
||||
*out_is_self_signed = (x->ex_flags & EXFLAG_SS) != 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Given a certificate try and find an exact match in the store */
|
||||
@@ -263,8 +265,14 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
|
||||
* X509_V_ERR_CERT_CHAIN_TOO_LONG error code
|
||||
* later. */
|
||||
|
||||
int is_self_signed;
|
||||
if (!cert_self_signed(x, &is_self_signed)) {
|
||||
ctx->error = X509_V_ERR_INVALID_EXTENSION;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* If we are self signed, we break */
|
||||
if (cert_self_signed(x))
|
||||
if (is_self_signed)
|
||||
break;
|
||||
/*
|
||||
* If asked see if we can find issuer in trusted store first
|
||||
@@ -323,7 +331,14 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
|
||||
*/
|
||||
i = sk_X509_num(ctx->chain);
|
||||
x = sk_X509_value(ctx->chain, i - 1);
|
||||
if (cert_self_signed(x)) {
|
||||
|
||||
int is_self_signed;
|
||||
if (!cert_self_signed(x, &is_self_signed)) {
|
||||
ctx->error = X509_V_ERR_INVALID_EXTENSION;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (is_self_signed) {
|
||||
/* we have a self signed certificate */
|
||||
if (sk_X509_num(ctx->chain) == 1) {
|
||||
/*
|
||||
@@ -368,8 +383,12 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
|
||||
/* If we have enough, we break */
|
||||
if (depth < num)
|
||||
break;
|
||||
if (!cert_self_signed(x, &is_self_signed)) {
|
||||
ctx->error = X509_V_ERR_INVALID_EXTENSION;
|
||||
goto end;
|
||||
}
|
||||
/* If we are self signed, we break */
|
||||
if (cert_self_signed(x))
|
||||
if (is_self_signed)
|
||||
break;
|
||||
ok = ctx->get_issuer(&xtmp, ctx, x);
|
||||
|
||||
|
||||
@@ -135,6 +135,11 @@ int X509_CRL_up_ref(X509_CRL *crl)
|
||||
return 1;
|
||||
}
|
||||
|
||||
long X509_CRL_get_version(const X509_CRL *crl)
|
||||
{
|
||||
return ASN1_INTEGER_get(crl->crl->version);
|
||||
}
|
||||
|
||||
const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl)
|
||||
{
|
||||
return crl->crl->lastUpdate;
|
||||
@@ -145,6 +150,26 @@ const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl)
|
||||
return crl->crl->nextUpdate;
|
||||
}
|
||||
|
||||
ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl)
|
||||
{
|
||||
return crl->crl->lastUpdate;
|
||||
}
|
||||
|
||||
ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl)
|
||||
{
|
||||
return crl->crl->nextUpdate;
|
||||
}
|
||||
|
||||
X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl)
|
||||
{
|
||||
return crl->crl->issuer;
|
||||
}
|
||||
|
||||
STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl)
|
||||
{
|
||||
return crl->crl->revoked;
|
||||
}
|
||||
|
||||
void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig,
|
||||
const X509_ALGOR **palg)
|
||||
{
|
||||
|
||||
+35
-13
@@ -86,7 +86,7 @@ struct x509_crl_method_st {
|
||||
};
|
||||
|
||||
static int X509_REVOKED_cmp(const X509_REVOKED **a, const X509_REVOKED **b);
|
||||
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
|
||||
static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
|
||||
|
||||
ASN1_SEQUENCE(X509_REVOKED) = {
|
||||
ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
|
||||
@@ -126,6 +126,9 @@ static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
* affect the output of X509_CRL_print().
|
||||
*/
|
||||
case ASN1_OP_D2I_POST:
|
||||
/* TODO(davidben): Check that default |versions| are never encoded and
|
||||
* that |extensions| is only present in v2. */
|
||||
|
||||
(void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp);
|
||||
break;
|
||||
}
|
||||
@@ -226,6 +229,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
STACK_OF(X509_EXTENSION) *exts;
|
||||
X509_EXTENSION *ext;
|
||||
size_t idx;
|
||||
int i;
|
||||
|
||||
switch (operation) {
|
||||
case ASN1_OP_NEW_POST:
|
||||
@@ -242,26 +246,44 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
break;
|
||||
|
||||
case ASN1_OP_D2I_POST:
|
||||
X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
|
||||
if (!X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
crl->idp = X509_CRL_get_ext_d2i(crl,
|
||||
NID_issuing_distribution_point, NULL,
|
||||
NID_issuing_distribution_point, &i,
|
||||
NULL);
|
||||
if (crl->idp)
|
||||
setup_idp(crl, crl->idp);
|
||||
if (crl->idp != NULL) {
|
||||
if (!setup_idp(crl, crl->idp)) {
|
||||
return 0;
|
||||
}
|
||||
} else if (i != -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
crl->akid = X509_CRL_get_ext_d2i(crl,
|
||||
NID_authority_key_identifier, NULL,
|
||||
NID_authority_key_identifier, &i,
|
||||
NULL);
|
||||
if (crl->akid == NULL && i != -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
crl->crl_number = X509_CRL_get_ext_d2i(crl,
|
||||
NID_crl_number, NULL, NULL);
|
||||
NID_crl_number, &i, NULL);
|
||||
if (crl->crl_number == NULL && i != -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
|
||||
NID_delta_crl, NULL,
|
||||
crl->base_crl_number = X509_CRL_get_ext_d2i(crl, NID_delta_crl, &i,
|
||||
NULL);
|
||||
if (crl->base_crl_number == NULL && i != -1) {
|
||||
return 0;
|
||||
}
|
||||
/* Delta CRLs must have CRL number */
|
||||
if (crl->base_crl_number && !crl->crl_number)
|
||||
crl->flags |= EXFLAG_INVALID;
|
||||
if (crl->base_crl_number && !crl->crl_number) {
|
||||
OPENSSL_PUT_ERROR(X509, X509_R_DELTA_CRL_WITHOUT_CRL_NUMBER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we have any unhandled critical CRL extensions and indicate
|
||||
@@ -319,7 +341,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
|
||||
/* Convert IDP into a more convenient form */
|
||||
|
||||
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
|
||||
static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
|
||||
{
|
||||
int idp_only = 0;
|
||||
/* Set various flags according to IDP */
|
||||
@@ -352,7 +374,7 @@ static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
|
||||
crl->idp_reasons &= CRLDP_ALL_REASONS;
|
||||
}
|
||||
|
||||
DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
|
||||
return DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
|
||||
}
|
||||
|
||||
ASN1_SEQUENCE_ref(X509_CRL, crl_cb) = {
|
||||
|
||||
@@ -180,160 +180,6 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or
|
||||
* decode as X509_PUBKEY
|
||||
*/
|
||||
|
||||
EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
|
||||
{
|
||||
X509_PUBKEY *xpk;
|
||||
EVP_PKEY *pktmp;
|
||||
xpk = d2i_X509_PUBKEY(NULL, pp, length);
|
||||
if (!xpk)
|
||||
return NULL;
|
||||
pktmp = X509_PUBKEY_get(xpk);
|
||||
X509_PUBKEY_free(xpk);
|
||||
if (!pktmp)
|
||||
return NULL;
|
||||
if (a) {
|
||||
EVP_PKEY_free(*a);
|
||||
*a = pktmp;
|
||||
}
|
||||
return pktmp;
|
||||
}
|
||||
|
||||
int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp)
|
||||
{
|
||||
X509_PUBKEY *xpk = NULL;
|
||||
int ret;
|
||||
if (!a)
|
||||
return 0;
|
||||
if (!X509_PUBKEY_set(&xpk, (EVP_PKEY *)a))
|
||||
return 0;
|
||||
ret = i2d_X509_PUBKEY(xpk, pp);
|
||||
X509_PUBKEY_free(xpk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following are equivalents but which return RSA and DSA keys
|
||||
*/
|
||||
RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
RSA *key;
|
||||
const unsigned char *q;
|
||||
q = *pp;
|
||||
pkey = d2i_PUBKEY(NULL, &q, length);
|
||||
if (!pkey)
|
||||
return NULL;
|
||||
key = EVP_PKEY_get1_RSA(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
if (!key)
|
||||
return NULL;
|
||||
*pp = q;
|
||||
if (a) {
|
||||
RSA_free(*a);
|
||||
*a = key;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
int i2d_RSA_PUBKEY(const RSA *a, unsigned char **pp)
|
||||
{
|
||||
EVP_PKEY *pktmp;
|
||||
int ret;
|
||||
if (!a)
|
||||
return 0;
|
||||
pktmp = EVP_PKEY_new();
|
||||
if (!pktmp) {
|
||||
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
EVP_PKEY_set1_RSA(pktmp, (RSA *)a);
|
||||
ret = i2d_PUBKEY(pktmp, pp);
|
||||
EVP_PKEY_free(pktmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
DSA *key;
|
||||
const unsigned char *q;
|
||||
q = *pp;
|
||||
pkey = d2i_PUBKEY(NULL, &q, length);
|
||||
if (!pkey)
|
||||
return NULL;
|
||||
key = EVP_PKEY_get1_DSA(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
if (!key)
|
||||
return NULL;
|
||||
*pp = q;
|
||||
if (a) {
|
||||
DSA_free(*a);
|
||||
*a = key;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp)
|
||||
{
|
||||
EVP_PKEY *pktmp;
|
||||
int ret;
|
||||
if (!a)
|
||||
return 0;
|
||||
pktmp = EVP_PKEY_new();
|
||||
if (!pktmp) {
|
||||
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
EVP_PKEY_set1_DSA(pktmp, (DSA *)a);
|
||||
ret = i2d_PUBKEY(pktmp, pp);
|
||||
EVP_PKEY_free(pktmp);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
EC_KEY *key;
|
||||
const unsigned char *q;
|
||||
q = *pp;
|
||||
pkey = d2i_PUBKEY(NULL, &q, length);
|
||||
if (!pkey)
|
||||
return (NULL);
|
||||
key = EVP_PKEY_get1_EC_KEY(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
if (!key)
|
||||
return (NULL);
|
||||
*pp = q;
|
||||
if (a) {
|
||||
EC_KEY_free(*a);
|
||||
*a = key;
|
||||
}
|
||||
return (key);
|
||||
}
|
||||
|
||||
int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp)
|
||||
{
|
||||
EVP_PKEY *pktmp;
|
||||
int ret;
|
||||
if (!a)
|
||||
return (0);
|
||||
if ((pktmp = EVP_PKEY_new()) == NULL) {
|
||||
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
|
||||
return (0);
|
||||
}
|
||||
EVP_PKEY_set1_EC_KEY(pktmp, (EC_KEY *)a);
|
||||
ret = i2d_PUBKEY(pktmp, pp);
|
||||
EVP_PKEY_free(pktmp);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int X509_PUBKEY_set0_param(X509_PUBKEY *pub, const ASN1_OBJECT *aobj,
|
||||
int ptype, void *pval,
|
||||
unsigned char *penc, int penclen)
|
||||
|
||||
@@ -67,3 +67,23 @@ ASN1_SEQUENCE(X509_SIG) = {
|
||||
} ASN1_SEQUENCE_END(X509_SIG)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(X509_SIG)
|
||||
|
||||
void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **out_alg,
|
||||
const ASN1_OCTET_STRING **out_digest) {
|
||||
if (out_alg != NULL) {
|
||||
*out_alg = sig->algor;
|
||||
}
|
||||
if (out_digest != NULL) {
|
||||
*out_digest = sig->digest;
|
||||
}
|
||||
}
|
||||
|
||||
void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **out_alg,
|
||||
ASN1_OCTET_STRING **out_digest) {
|
||||
if (out_alg != NULL) {
|
||||
*out_alg = sig->algor;
|
||||
}
|
||||
if (out_digest != NULL) {
|
||||
*out_digest = sig->digest;
|
||||
}
|
||||
}
|
||||
|
||||
+28
-6
@@ -98,7 +98,6 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
switch (operation) {
|
||||
|
||||
case ASN1_OP_NEW_POST:
|
||||
ret->name = NULL;
|
||||
ret->ex_flags = 0;
|
||||
ret->ex_pathlen = -1;
|
||||
ret->skid = NULL;
|
||||
@@ -115,11 +114,35 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
ret->buf = NULL;
|
||||
break;
|
||||
|
||||
case ASN1_OP_D2I_POST:
|
||||
if (ret->name != NULL)
|
||||
OPENSSL_free(ret->name);
|
||||
ret->name = X509_NAME_oneline(ret->cert_info->subject, NULL, 0);
|
||||
case ASN1_OP_D2I_POST: {
|
||||
/* The version must be one of v1(0), v2(1), or v3(2). */
|
||||
long version = 0;
|
||||
if (ret->cert_info->version != NULL) {
|
||||
version = ASN1_INTEGER_get(ret->cert_info->version);
|
||||
/* TODO(https://crbug.com/boringssl/364): |version| = 0 should also
|
||||
* be rejected. This means an explicitly-encoded X.509v1 version.
|
||||
* v1 is DEFAULT, so DER requires it be omitted. */
|
||||
if (version < 0 || version > 2) {
|
||||
OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Per RFC5280, section 4.1.2.8, these fields require v2 or v3. */
|
||||
if (version == 0 && (ret->cert_info->issuerUID != NULL ||
|
||||
ret->cert_info->subjectUID != NULL)) {
|
||||
OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Per RFC5280, section 4.1.2.9, extensions require v3. */
|
||||
if (version != 2 && ret->cert_info->extensions != NULL) {
|
||||
OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ASN1_OP_FREE_POST:
|
||||
CRYPTO_MUTEX_cleanup(&ret->lock);
|
||||
@@ -132,7 +155,6 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
GENERAL_NAMES_free(ret->altname);
|
||||
NAME_CONSTRAINTS_free(ret->nc);
|
||||
CRYPTO_BUFFER_free(ret->buf);
|
||||
OPENSSL_free(ret->name);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
@@ -48,6 +48,11 @@ int x509v3_name_cmp(const char *name, const char *cmp);
|
||||
OPENSSL_EXPORT int x509v3_looks_like_dns_name(const unsigned char *in,
|
||||
size_t len);
|
||||
|
||||
// x509v3_cache_extensions fills in a number of fields relating to X.509
|
||||
// extensions in |x|. It returns one on success and zero if some extensions were
|
||||
// invalid.
|
||||
int x509v3_cache_extensions(X509 *x);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern C */
|
||||
|
||||
+75
-36
@@ -68,6 +68,7 @@
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "../internal.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
|
||||
#define ku_reject(x, usage) \
|
||||
@@ -77,8 +78,6 @@
|
||||
#define ns_reject(x, usage) \
|
||||
(((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
|
||||
|
||||
static void x509v3_cache_extensions(X509 *x);
|
||||
|
||||
static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
|
||||
int ca);
|
||||
static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
|
||||
@@ -144,7 +143,10 @@ int X509_check_purpose(X509 *x, int id, int ca)
|
||||
{
|
||||
int idx;
|
||||
const X509_PURPOSE *pt;
|
||||
x509v3_cache_extensions(x);
|
||||
if (!x509v3_cache_extensions(x)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (id == -1)
|
||||
return 1;
|
||||
idx = X509_PURPOSE_get_by_id(id);
|
||||
@@ -368,7 +370,7 @@ int X509_supported_extension(X509_EXTENSION *ex)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup_dp(X509 *x, DIST_POINT *dp)
|
||||
static int setup_dp(X509 *x, DIST_POINT *dp)
|
||||
{
|
||||
X509_NAME *iname = NULL;
|
||||
size_t i;
|
||||
@@ -381,7 +383,7 @@ static void setup_dp(X509 *x, DIST_POINT *dp)
|
||||
} else
|
||||
dp->dp_reasons = CRLDP_ALL_REASONS;
|
||||
if (!dp->distpoint || (dp->distpoint->type != 1))
|
||||
return;
|
||||
return 1;
|
||||
for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
|
||||
GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
|
||||
if (gen->type == GEN_DIRNAME) {
|
||||
@@ -392,19 +394,25 @@ static void setup_dp(X509 *x, DIST_POINT *dp)
|
||||
if (!iname)
|
||||
iname = X509_get_issuer_name(x);
|
||||
|
||||
DIST_POINT_set_dpname(dp->distpoint, iname);
|
||||
|
||||
return DIST_POINT_set_dpname(dp->distpoint, iname);
|
||||
}
|
||||
|
||||
static void setup_crldp(X509 *x)
|
||||
static int setup_crldp(X509 *x)
|
||||
{
|
||||
size_t i;
|
||||
x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
|
||||
for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
|
||||
setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
|
||||
int j;
|
||||
x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &j, NULL);
|
||||
if (x->crldp == NULL && j != -1) {
|
||||
return 0;
|
||||
}
|
||||
for (size_t i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
|
||||
if (!setup_dp(x, sk_DIST_POINT_value(x->crldp, i))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void x509v3_cache_extensions(X509 *x)
|
||||
int x509v3_cache_extensions(X509 *x)
|
||||
{
|
||||
BASIC_CONSTRAINTS *bs;
|
||||
PROXY_CERT_INFO_EXTENSION *pci;
|
||||
@@ -420,21 +428,22 @@ static void x509v3_cache_extensions(X509 *x)
|
||||
CRYPTO_MUTEX_unlock_read(&x->lock);
|
||||
|
||||
if (is_set) {
|
||||
return;
|
||||
return (x->ex_flags & EXFLAG_INVALID) == 0;
|
||||
}
|
||||
|
||||
CRYPTO_MUTEX_lock_write(&x->lock);
|
||||
if (x->ex_flags & EXFLAG_SET) {
|
||||
CRYPTO_MUTEX_unlock_write(&x->lock);
|
||||
return;
|
||||
return (x->ex_flags & EXFLAG_INVALID) == 0;
|
||||
}
|
||||
|
||||
X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
|
||||
if (!X509_digest(x, EVP_sha1(), x->sha1_hash, NULL))
|
||||
x->ex_flags |= EXFLAG_INVALID;
|
||||
/* V1 should mean no extensions ... */
|
||||
if (!X509_get_version(x))
|
||||
x->ex_flags |= EXFLAG_V1;
|
||||
/* Handle basic constraints */
|
||||
if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
|
||||
if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, &j, NULL))) {
|
||||
if (bs->ca)
|
||||
x->ex_flags |= EXFLAG_CA;
|
||||
if (bs->pathlen) {
|
||||
@@ -448,9 +457,11 @@ static void x509v3_cache_extensions(X509 *x)
|
||||
x->ex_pathlen = -1;
|
||||
BASIC_CONSTRAINTS_free(bs);
|
||||
x->ex_flags |= EXFLAG_BCONS;
|
||||
} else if (j != -1) {
|
||||
x->ex_flags |= EXFLAG_INVALID;
|
||||
}
|
||||
/* Handle proxy certificates */
|
||||
if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
|
||||
if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, &j, NULL))) {
|
||||
if (x->ex_flags & EXFLAG_CA
|
||||
|| X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0
|
||||
|| X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
|
||||
@@ -462,9 +473,11 @@ static void x509v3_cache_extensions(X509 *x)
|
||||
x->ex_pcpathlen = -1;
|
||||
PROXY_CERT_INFO_EXTENSION_free(pci);
|
||||
x->ex_flags |= EXFLAG_PROXY;
|
||||
} else if (j != -1) {
|
||||
x->ex_flags |= EXFLAG_INVALID;
|
||||
}
|
||||
/* Handle key usage */
|
||||
if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
|
||||
if ((usage = X509_get_ext_d2i(x, NID_key_usage, &j, NULL))) {
|
||||
if (usage->length > 0) {
|
||||
x->ex_kusage = usage->data[0];
|
||||
if (usage->length > 1)
|
||||
@@ -473,9 +486,11 @@ static void x509v3_cache_extensions(X509 *x)
|
||||
x->ex_kusage = 0;
|
||||
x->ex_flags |= EXFLAG_KUSAGE;
|
||||
ASN1_BIT_STRING_free(usage);
|
||||
} else if (j != -1) {
|
||||
x->ex_flags |= EXFLAG_INVALID;
|
||||
}
|
||||
x->ex_xkusage = 0;
|
||||
if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
|
||||
if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, &j, NULL))) {
|
||||
x->ex_flags |= EXFLAG_XKUSAGE;
|
||||
for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
|
||||
switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) {
|
||||
@@ -518,18 +533,28 @@ static void x509v3_cache_extensions(X509 *x)
|
||||
}
|
||||
}
|
||||
sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
|
||||
} else if (j != -1) {
|
||||
x->ex_flags |= EXFLAG_INVALID;
|
||||
}
|
||||
|
||||
if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
|
||||
if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, &j, NULL))) {
|
||||
if (ns->length > 0)
|
||||
x->ex_nscert = ns->data[0];
|
||||
else
|
||||
x->ex_nscert = 0;
|
||||
x->ex_flags |= EXFLAG_NSCERT;
|
||||
ASN1_BIT_STRING_free(ns);
|
||||
} else if (j != -1) {
|
||||
x->ex_flags |= EXFLAG_INVALID;
|
||||
}
|
||||
x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, &j, NULL);
|
||||
if (x->skid == NULL && j != -1) {
|
||||
x->ex_flags |= EXFLAG_INVALID;
|
||||
}
|
||||
x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, &j, NULL);
|
||||
if (x->akid == NULL && j != -1) {
|
||||
x->ex_flags |= EXFLAG_INVALID;
|
||||
}
|
||||
x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
|
||||
x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
|
||||
/* Does subject name match issuer ? */
|
||||
if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
|
||||
x->ex_flags |= EXFLAG_SI;
|
||||
@@ -538,11 +563,17 @@ static void x509v3_cache_extensions(X509 *x)
|
||||
!ku_reject(x, KU_KEY_CERT_SIGN))
|
||||
x->ex_flags |= EXFLAG_SS;
|
||||
}
|
||||
x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
|
||||
x->nc = X509_get_ext_d2i(x, NID_name_constraints, &j, NULL);
|
||||
if (!x->nc && (j != -1))
|
||||
x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, &j, NULL);
|
||||
if (x->altname == NULL && j != -1) {
|
||||
x->ex_flags |= EXFLAG_INVALID;
|
||||
setup_crldp(x);
|
||||
}
|
||||
x->nc = X509_get_ext_d2i(x, NID_name_constraints, &j, NULL);
|
||||
if (x->nc == NULL && j != -1) {
|
||||
x->ex_flags |= EXFLAG_INVALID;
|
||||
}
|
||||
if (!setup_crldp(x)) {
|
||||
x->ex_flags |= EXFLAG_INVALID;
|
||||
}
|
||||
|
||||
for (j = 0; j < X509_get_ext_count(x); j++) {
|
||||
ex = X509_get_ext(x, j);
|
||||
@@ -559,6 +590,7 @@ static void x509v3_cache_extensions(X509 *x)
|
||||
x->ex_flags |= EXFLAG_SET;
|
||||
|
||||
CRYPTO_MUTEX_unlock_write(&x->lock);
|
||||
return (x->ex_flags & EXFLAG_INVALID) == 0;
|
||||
}
|
||||
|
||||
/* check_ca returns one if |x| should be considered a CA certificate and zero
|
||||
@@ -579,7 +611,9 @@ static int check_ca(const X509 *x)
|
||||
|
||||
int X509_check_ca(X509 *x)
|
||||
{
|
||||
x509v3_cache_extensions(x);
|
||||
if (!x509v3_cache_extensions(x)) {
|
||||
return 0;
|
||||
}
|
||||
return check_ca(x);
|
||||
}
|
||||
|
||||
@@ -761,8 +795,10 @@ int X509_check_issued(X509 *issuer, X509 *subject)
|
||||
if (X509_NAME_cmp(X509_get_subject_name(issuer),
|
||||
X509_get_issuer_name(subject)))
|
||||
return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
|
||||
x509v3_cache_extensions(issuer);
|
||||
x509v3_cache_extensions(subject);
|
||||
if (!x509v3_cache_extensions(issuer) ||
|
||||
!x509v3_cache_extensions(subject)) {
|
||||
return X509_V_ERR_UNSPECIFIED;
|
||||
}
|
||||
|
||||
if (subject->akid) {
|
||||
int ret = X509_check_akid(issuer, subject->akid);
|
||||
@@ -819,15 +855,17 @@ int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
|
||||
|
||||
uint32_t X509_get_extension_flags(X509 *x)
|
||||
{
|
||||
/* Call for side-effect of computing hash and caching extensions */
|
||||
X509_check_purpose(x, -1, -1);
|
||||
if (!x509v3_cache_extensions(x)) {
|
||||
return 0;
|
||||
}
|
||||
return x->ex_flags;
|
||||
}
|
||||
|
||||
uint32_t X509_get_key_usage(X509 *x)
|
||||
{
|
||||
/* Call for side-effect of computing hash and caching extensions */
|
||||
X509_check_purpose(x, -1, -1);
|
||||
if (!x509v3_cache_extensions(x)) {
|
||||
return 0;
|
||||
}
|
||||
if (x->ex_flags & EXFLAG_KUSAGE)
|
||||
return x->ex_kusage;
|
||||
return UINT32_MAX;
|
||||
@@ -835,8 +873,9 @@ uint32_t X509_get_key_usage(X509 *x)
|
||||
|
||||
uint32_t X509_get_extended_key_usage(X509 *x)
|
||||
{
|
||||
/* Call for side-effect of computing hash and caching extensions */
|
||||
X509_check_purpose(x, -1, -1);
|
||||
if (!x509v3_cache_extensions(x)) {
|
||||
return 0;
|
||||
}
|
||||
if (x->ex_flags & EXFLAG_XKUSAGE)
|
||||
return x->ex_xkusage;
|
||||
return UINT32_MAX;
|
||||
|
||||
@@ -513,17 +513,10 @@ static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) {
|
||||
}
|
||||
|
||||
static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb fp) {
|
||||
long ret = 1;
|
||||
|
||||
if (b->next_bio == NULL) {
|
||||
return 0;
|
||||
}
|
||||
switch (cmd) {
|
||||
default:
|
||||
ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
return BIO_callback_ctrl(b->next_bio, cmd, fp);
|
||||
}
|
||||
|
||||
static const BIO_METHOD b64_method = {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
module boringssl.googlesource.com/boringssl
|
||||
|
||||
go 1.13
|
||||
|
||||
require golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
+16
-4
@@ -106,7 +106,10 @@ OPENSSL_EXPORT void AES_decrypt(const uint8_t *in, uint8_t *out,
|
||||
|
||||
// AES_ctr128_encrypt encrypts (or decrypts, it's the same in CTR mode) |len|
|
||||
// bytes from |in| to |out|. The |num| parameter must be set to zero on the
|
||||
// first call and |ivec| will be incremented.
|
||||
// first call and |ivec| will be incremented. This function may be called
|
||||
// in-place with |in| equal to |out|, but otherwise the buffers may not
|
||||
// partially overlap. A partial overlap may overwrite input data before it is
|
||||
// read.
|
||||
OPENSSL_EXPORT void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
uint8_t ivec[AES_BLOCK_SIZE],
|
||||
@@ -114,26 +117,35 @@ OPENSSL_EXPORT void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out,
|
||||
unsigned int *num);
|
||||
|
||||
// AES_ecb_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) a single,
|
||||
// 16 byte block from |in| to |out|.
|
||||
// 16 byte block from |in| to |out|. This function may be called in-place with
|
||||
// |in| equal to |out|, but otherwise the buffers may not partially overlap. A
|
||||
// partial overlap may overwrite input data before it is read.
|
||||
OPENSSL_EXPORT void AES_ecb_encrypt(const uint8_t *in, uint8_t *out,
|
||||
const AES_KEY *key, const int enc);
|
||||
|
||||
// AES_cbc_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len|
|
||||
// bytes from |in| to |out|. The length must be a multiple of the block size.
|
||||
// This function may be called in-place with |in| equal to |out|, but otherwise
|
||||
// the buffers may not partially overlap. A partial overlap may overwrite input
|
||||
// data before it is read.
|
||||
OPENSSL_EXPORT void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
|
||||
const AES_KEY *key, uint8_t *ivec,
|
||||
const int enc);
|
||||
|
||||
// AES_ofb128_encrypt encrypts (or decrypts, it's the same in OFB mode) |len|
|
||||
// bytes from |in| to |out|. The |num| parameter must be set to zero on the
|
||||
// first call.
|
||||
// first call. This function may be called in-place with |in| equal to |out|,
|
||||
// but otherwise the buffers may not partially overlap. A partial overlap may
|
||||
// overwrite input data before it is read.
|
||||
OPENSSL_EXPORT void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
uint8_t *ivec, int *num);
|
||||
|
||||
// AES_cfb128_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len|
|
||||
// bytes from |in| to |out|. The |num| parameter must be set to zero on the
|
||||
// first call.
|
||||
// first call. This function may be called in-place with |in| equal to |out|,
|
||||
// but otherwise the buffers may not partially overlap. A partial overlap may
|
||||
// overwrite input data before it is read.
|
||||
OPENSSL_EXPORT void AES_cfb128_encrypt(const uint8_t *in, uint8_t *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
uint8_t *ivec, int *num, int enc);
|
||||
|
||||
+22
-22
@@ -619,14 +619,14 @@ typedef struct BIT_STRING_BITNAME_st {
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
|
||||
|
||||
OPENSSL_EXPORT int ASN1_TYPE_get(ASN1_TYPE *a);
|
||||
OPENSSL_EXPORT int ASN1_TYPE_get(const ASN1_TYPE *a);
|
||||
OPENSSL_EXPORT void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
|
||||
OPENSSL_EXPORT int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
|
||||
OPENSSL_EXPORT int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
|
||||
|
||||
OPENSSL_EXPORT ASN1_OBJECT * ASN1_OBJECT_new(void );
|
||||
OPENSSL_EXPORT void ASN1_OBJECT_free(ASN1_OBJECT *a);
|
||||
OPENSSL_EXPORT int i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp);
|
||||
OPENSSL_EXPORT int i2d_ASN1_OBJECT(const ASN1_OBJECT *a,unsigned char **pp);
|
||||
OPENSSL_EXPORT ASN1_OBJECT * c2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
|
||||
long length);
|
||||
OPENSSL_EXPORT ASN1_OBJECT * d2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
|
||||
@@ -648,23 +648,23 @@ OPENSSL_EXPORT int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len
|
||||
OPENSSL_EXPORT void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
|
||||
OPENSSL_EXPORT int ASN1_STRING_length(const ASN1_STRING *x);
|
||||
OPENSSL_EXPORT void ASN1_STRING_length_set(ASN1_STRING *x, int n);
|
||||
OPENSSL_EXPORT int ASN1_STRING_type(ASN1_STRING *x);
|
||||
OPENSSL_EXPORT int ASN1_STRING_type(const ASN1_STRING *x);
|
||||
OPENSSL_EXPORT unsigned char * ASN1_STRING_data(ASN1_STRING *x);
|
||||
OPENSSL_EXPORT const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x);
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
|
||||
OPENSSL_EXPORT int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp);
|
||||
OPENSSL_EXPORT int i2c_ASN1_BIT_STRING(const ASN1_BIT_STRING *a,unsigned char **pp);
|
||||
OPENSSL_EXPORT ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,const unsigned char **pp, long length);
|
||||
OPENSSL_EXPORT int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length );
|
||||
OPENSSL_EXPORT int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
|
||||
OPENSSL_EXPORT int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
|
||||
OPENSSL_EXPORT int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, unsigned char *flags, int flags_len);
|
||||
OPENSSL_EXPORT int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n);
|
||||
OPENSSL_EXPORT int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a, unsigned char *flags, int flags_len);
|
||||
|
||||
OPENSSL_EXPORT int i2d_ASN1_BOOLEAN(int a,unsigned char **pp);
|
||||
OPENSSL_EXPORT int d2i_ASN1_BOOLEAN(int *a,const unsigned char **pp,long length);
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
|
||||
OPENSSL_EXPORT int i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp);
|
||||
OPENSSL_EXPORT int i2c_ASN1_INTEGER(const ASN1_INTEGER *a,unsigned char **pp);
|
||||
OPENSSL_EXPORT ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp, long length);
|
||||
OPENSSL_EXPORT ASN1_INTEGER * ASN1_INTEGER_dup(const ASN1_INTEGER *x);
|
||||
OPENSSL_EXPORT int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
|
||||
@@ -713,15 +713,15 @@ DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
|
||||
|
||||
OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
|
||||
OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s,time_t t, int offset_day, long offset_sec);
|
||||
OPENSSL_EXPORT int ASN1_TIME_check(ASN1_TIME *t);
|
||||
OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
|
||||
OPENSSL_EXPORT int ASN1_TIME_check(const ASN1_TIME *t);
|
||||
OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
|
||||
OPENSSL_EXPORT int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
|
||||
|
||||
OPENSSL_EXPORT int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
|
||||
OPENSSL_EXPORT int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a);
|
||||
OPENSSL_EXPORT int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a);
|
||||
OPENSSL_EXPORT int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type);
|
||||
OPENSSL_EXPORT int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a);
|
||||
OPENSSL_EXPORT int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a);
|
||||
OPENSSL_EXPORT int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a);
|
||||
OPENSSL_EXPORT int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a);
|
||||
OPENSSL_EXPORT int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type);
|
||||
OPENSSL_EXPORT int i2t_ASN1_OBJECT(char *buf,int buf_len, const ASN1_OBJECT *a);
|
||||
|
||||
OPENSSL_EXPORT ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len, const char *sn, const char *ln);
|
||||
|
||||
@@ -732,9 +732,9 @@ OPENSSL_EXPORT ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *
|
||||
OPENSSL_EXPORT BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai,BIGNUM *bn);
|
||||
|
||||
OPENSSL_EXPORT int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
|
||||
OPENSSL_EXPORT long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
|
||||
OPENSSL_EXPORT ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai);
|
||||
OPENSSL_EXPORT BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai,BIGNUM *bn);
|
||||
OPENSSL_EXPORT long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a);
|
||||
OPENSSL_EXPORT ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai);
|
||||
OPENSSL_EXPORT BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai,BIGNUM *bn);
|
||||
|
||||
/* General */
|
||||
/* given a string, return the correct type, max is the maximum length */
|
||||
@@ -753,7 +753,7 @@ OPENSSL_EXPORT void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
|
||||
#ifndef OPENSSL_NO_FP_API
|
||||
OPENSSL_EXPORT void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
|
||||
OPENSSL_EXPORT int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
|
||||
OPENSSL_EXPORT int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
|
||||
OPENSSL_EXPORT int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, unsigned long flags);
|
||||
#endif
|
||||
|
||||
OPENSSL_EXPORT int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
|
||||
@@ -764,12 +764,12 @@ OPENSSL_EXPORT int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
|
||||
OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
|
||||
OPENSSL_EXPORT int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
|
||||
OPENSSL_EXPORT int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
|
||||
OPENSSL_EXPORT int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
|
||||
OPENSSL_EXPORT int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, unsigned long flags);
|
||||
OPENSSL_EXPORT const char *ASN1_tag2str(int tag);
|
||||
|
||||
/* Used to load and write netscape format cert */
|
||||
|
||||
OPENSSL_EXPORT void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
|
||||
OPENSSL_EXPORT void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it);
|
||||
|
||||
OPENSSL_EXPORT ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct);
|
||||
|
||||
@@ -793,8 +793,8 @@ OPENSSL_EXPORT ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, const unsigned char
|
||||
OPENSSL_EXPORT int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
|
||||
OPENSSL_EXPORT int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
|
||||
|
||||
OPENSSL_EXPORT ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
|
||||
OPENSSL_EXPORT ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
|
||||
OPENSSL_EXPORT ASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf);
|
||||
OPENSSL_EXPORT ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -90,7 +90,7 @@ extern "C" {
|
||||
#elif defined(__x86) || defined(__i386) || defined(__i386__) || defined(_M_IX86)
|
||||
#define OPENSSL_32_BIT
|
||||
#define OPENSSL_X86
|
||||
#elif defined(__aarch64__)
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||
#define OPENSSL_64_BIT
|
||||
#define OPENSSL_AARCH64
|
||||
#elif defined(__arm) || defined(__arm__) || defined(_M_ARM)
|
||||
@@ -184,7 +184,7 @@ extern "C" {
|
||||
// A consumer may use this symbol in the preprocessor to temporarily build
|
||||
// against multiple revisions of BoringSSL at the same time. It is not
|
||||
// recommended to do so for longer than is necessary.
|
||||
#define BORINGSSL_API_VERSION 10
|
||||
#define BORINGSSL_API_VERSION 11
|
||||
|
||||
#if defined(BORINGSSL_SHARED_LIBRARY)
|
||||
|
||||
|
||||
@@ -947,6 +947,75 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx,
|
||||
OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(EVP_PKEY_CTX *ctx,
|
||||
const EVP_MD *md);
|
||||
|
||||
// i2d_PUBKEY marshals a public key from |pkey| as a DER-encoded
|
||||
// SubjectPublicKeyInfo. If |outp| is not NULL, the result is written to |*outp|
|
||||
// and |*outp| is advanced just past the output. It returns the number of bytes
|
||||
// in the result, whether written or not, or a negative value on error.
|
||||
//
|
||||
// Use |EVP_marshal_public_key| instead.
|
||||
OPENSSL_EXPORT int i2d_PUBKEY(const EVP_PKEY *pkey, uint8_t **outp);
|
||||
|
||||
// d2i_PUBKEY parses a DER-encoded SubjectPublicKeyInfo from |len| bytes at
|
||||
// |*inp|. It returns a newly-allocated result, or NULL on error. On success,
|
||||
// |*inp| is advanced past the DER structure. If |out| is not NULL, it also
|
||||
// frees any existing object pointed by |*out| and writes the result.
|
||||
//
|
||||
// Use |EVP_parse_public_key| instead.
|
||||
OPENSSL_EXPORT EVP_PKEY *d2i_PUBKEY(EVP_PKEY **out, const uint8_t **inp,
|
||||
long len);
|
||||
|
||||
// i2d_RSA_PUBKEY marshals |rsa| as a DER-encoded SubjectPublicKeyInfo. If
|
||||
// |outp| is not NULL, the result is written to |*outp| and
|
||||
// |*outp| is advanced just past the output. It returns the number of bytes in
|
||||
// the result, whether written or not, or a negative value on error.
|
||||
//
|
||||
// Use |EVP_marshal_public_key| instead.
|
||||
OPENSSL_EXPORT int i2d_RSA_PUBKEY(const RSA *rsa, uint8_t **outp);
|
||||
|
||||
// d2i_RSA_PUBKEY parses an RSA public key as a DER-encoded SubjectPublicKeyInfo
|
||||
// from |len| bytes at |*inp|. It returns a newly-allocated result, or NULL on
|
||||
// error. On success, |*inp| is advanced past the DER structure. If |out| is not
|
||||
// NULL, it also frees any existing object pointed by |*out| and writes the
|
||||
// result.
|
||||
//
|
||||
// Use |EVP_parse_public_key| instead.
|
||||
OPENSSL_EXPORT RSA *d2i_RSA_PUBKEY(RSA **out, const uint8_t **inp, long len);
|
||||
|
||||
// i2d_DSA_PUBKEY marshals |dsa| as a DER-encoded SubjectPublicKeyInfo. If
|
||||
// |outp| is not NULL, the result is written to |*outp| and |*outp| is advanced
|
||||
// just past the output. It returns the number of bytes in the result, whether
|
||||
// written or not, or a negative value on error.
|
||||
//
|
||||
// Use |EVP_marshal_public_key| instead.
|
||||
OPENSSL_EXPORT int i2d_DSA_PUBKEY(const DSA *dsa, uint8_t **outp);
|
||||
|
||||
// d2i_DSA_PUBKEY parses a DSA public key as a DER-encoded SubjectPublicKeyInfo
|
||||
// from |len| bytes at |*inp|. It returns a newly-allocated result, or NULL on
|
||||
// error. On success, |*inp| is advanced past the DER structure. If |out| is not
|
||||
// NULL, it also frees any existing object pointed by |*out| and writes the
|
||||
// result.
|
||||
//
|
||||
// Use |EVP_parse_public_key| instead.
|
||||
OPENSSL_EXPORT DSA *d2i_DSA_PUBKEY(DSA **out, const uint8_t **inp, long len);
|
||||
|
||||
// i2d_EC_PUBKEY marshals |ec_key| as a DER-encoded SubjectPublicKeyInfo. If
|
||||
// |outp| is not NULL, the result is written to |*outp| and |*outp| is advanced
|
||||
// just past the output. It returns the number of bytes in the result, whether
|
||||
// written or not, or a negative value on error.
|
||||
//
|
||||
// Use |EVP_marshal_public_key| instead.
|
||||
OPENSSL_EXPORT int i2d_EC_PUBKEY(const EC_KEY *ec_key, uint8_t **outp);
|
||||
|
||||
// d2i_EC_PUBKEY parses an EC public key as a DER-encoded SubjectPublicKeyInfo
|
||||
// from |len| bytes at |*inp|. It returns a newly-allocated result, or NULL on
|
||||
// error. On success, |*inp| is advanced past the DER structure. If |out| is not
|
||||
// NULL, it also frees any existing object pointed by |*out| and writes the
|
||||
// result.
|
||||
//
|
||||
// Use |EVP_parse_public_key| instead.
|
||||
OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY(EC_KEY **out, const uint8_t **inp,
|
||||
long len);
|
||||
|
||||
|
||||
// Preprocessor compatibility section (hidden).
|
||||
//
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user