Chromium's OCSP code needs the OIDs and we already have them on hand. Change-Id: Icab012ba4ae15ce029cbfe3ed93f89470137e7f6 Reviewed-on: https://boringssl-review.googlesource.com/20724 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Steven Valdez <svaldez@google.com> Reviewed-by: Steven Valdez <svaldez@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>kris/onging/CECPQ3_patch15
@@ -62,7 +62,6 @@ | |||
#include <openssl/bytestring.h> | |||
#include <openssl/nid.h> | |||
#include "internal.h" | |||
#include "../internal.h" | |||
@@ -120,22 +119,22 @@ const EVP_MD* EVP_get_digestbynid(int nid) { | |||
static const struct { | |||
uint8_t oid[9]; | |||
uint8_t oid_len; | |||
const EVP_MD *(*md_func) (void); | |||
int nid; | |||
} kMDOIDs[] = { | |||
// 1.2.840.113549.2.4 | |||
{ {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x04}, 8, EVP_md4 }, | |||
{ {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x04}, 8, NID_md4 }, | |||
// 1.2.840.113549.2.5 | |||
{ {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05}, 8, EVP_md5 }, | |||
{ {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05}, 8, NID_md5 }, | |||
// 1.3.14.3.2.26 | |||
{ {0x2b, 0x0e, 0x03, 0x02, 0x1a}, 5, EVP_sha1 }, | |||
{ {0x2b, 0x0e, 0x03, 0x02, 0x1a}, 5, NID_sha1 }, | |||
// 2.16.840.1.101.3.4.2.1 | |||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01}, 9, EVP_sha256 }, | |||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01}, 9, NID_sha256 }, | |||
// 2.16.840.1.101.3.4.2.2 | |||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02}, 9, EVP_sha384 }, | |||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02}, 9, NID_sha384 }, | |||
// 2.16.840.1.101.3.4.2.3 | |||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03}, 9, EVP_sha512 }, | |||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03}, 9, NID_sha512 }, | |||
// 2.16.840.1.101.3.4.2.4 | |||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04}, 9, EVP_sha224 }, | |||
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04}, 9, NID_sha224 }, | |||
}; | |||
static const EVP_MD *cbs_to_md(const CBS *cbs) { | |||
@@ -143,7 +142,7 @@ static const EVP_MD *cbs_to_md(const CBS *cbs) { | |||
if (CBS_len(cbs) == kMDOIDs[i].oid_len && | |||
OPENSSL_memcmp(CBS_data(cbs), kMDOIDs[i].oid, kMDOIDs[i].oid_len) == | |||
0) { | |||
return kMDOIDs[i].md_func(); | |||
return EVP_get_digestbynid(kMDOIDs[i].nid); | |||
} | |||
} | |||
@@ -192,6 +191,41 @@ const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs) { | |||
return ret; | |||
} | |||
int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md) { | |||
CBB algorithm, oid, null; | |||
if (!CBB_add_asn1(cbb, &algorithm, CBS_ASN1_SEQUENCE) || | |||
!CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) { | |||
OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); | |||
return 0; | |||
} | |||
int found = 0; | |||
int nid = EVP_MD_type(md); | |||
for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) { | |||
if (nid == kMDOIDs[i].nid) { | |||
if (!CBB_add_bytes(&oid, kMDOIDs[i].oid, kMDOIDs[i].oid_len)) { | |||
OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); | |||
return 0; | |||
} | |||
found = 1; | |||
break; | |||
} | |||
} | |||
if (!found) { | |||
OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_UNKNOWN_HASH); | |||
return 0; | |||
} | |||
if (!CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || | |||
!CBB_flush(cbb)) { | |||
OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); | |||
return 0; | |||
} | |||
return 1; | |||
} | |||
const EVP_MD *EVP_get_digestbyname(const char *name) { | |||
for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(nid_to_digest_mapping); i++) { | |||
const char *short_name = nid_to_digest_mapping[i].short_name; | |||
@@ -21,6 +21,7 @@ | |||
#include <gtest/gtest.h> | |||
#include <openssl/asn1.h> | |||
#include <openssl/bytestring.h> | |||
#include <openssl/crypto.h> | |||
#include <openssl/digest.h> | |||
#include <openssl/err.h> | |||
@@ -31,6 +32,7 @@ | |||
#include <openssl/sha.h> | |||
#include "../internal.h" | |||
#include "../test/test_util.h" | |||
struct MD { | |||
@@ -215,3 +217,44 @@ TEST(DigestTest, Getters) { | |||
EXPECT_EQ(EVP_md5_sha1(), EVP_get_digestbyobj(OBJ_nid2obj(NID_md5_sha1))); | |||
EXPECT_EQ(EVP_sha1(), EVP_get_digestbyobj(OBJ_nid2obj(NID_sha1))); | |||
} | |||
TEST(DigestTest, ASN1) { | |||
bssl::ScopedCBB cbb; | |||
ASSERT_TRUE(CBB_init(cbb.get(), 0)); | |||
EXPECT_FALSE(EVP_marshal_digest_algorithm(cbb.get(), EVP_md5_sha1())); | |||
static const uint8_t kSHA256[] = {0x30, 0x0d, 0x06, 0x09, 0x60, | |||
0x86, 0x48, 0x01, 0x65, 0x03, | |||
0x04, 0x02, 0x01, 0x05, 0x00}; | |||
static const uint8_t kSHA256NoParam[] = {0x30, 0x0b, 0x06, 0x09, 0x60, | |||
0x86, 0x48, 0x01, 0x65, 0x03, | |||
0x04, 0x02, 0x01}; | |||
static const uint8_t kSHA256GarbageParam[] = { | |||
0x30, 0x0e, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, | |||
0x65, 0x03, 0x04, 0x02, 0x01, 0x02, 0x01, 0x2a}; | |||
// Serialize SHA-256. | |||
cbb.Reset(); | |||
ASSERT_TRUE(CBB_init(cbb.get(), 0)); | |||
ASSERT_TRUE(EVP_marshal_digest_algorithm(cbb.get(), EVP_sha256())); | |||
uint8_t *der; | |||
size_t der_len; | |||
ASSERT_TRUE(CBB_finish(cbb.get(), &der, &der_len)); | |||
bssl::UniquePtr<uint8_t> free_der(der); | |||
EXPECT_EQ(Bytes(kSHA256), Bytes(der, der_len)); | |||
// Parse SHA-256. | |||
CBS cbs; | |||
CBS_init(&cbs, kSHA256, sizeof(kSHA256)); | |||
EXPECT_EQ(EVP_sha256(), EVP_parse_digest_algorithm(&cbs)); | |||
EXPECT_EQ(0u, CBS_len(&cbs)); | |||
// Missing parameters are tolerated for compatibility. | |||
CBS_init(&cbs, kSHA256NoParam, sizeof(kSHA256NoParam)); | |||
EXPECT_EQ(EVP_sha256(), EVP_parse_digest_algorithm(&cbs)); | |||
EXPECT_EQ(0u, CBS_len(&cbs)); | |||
// Garbage parameters are not. | |||
CBS_init(&cbs, kSHA256GarbageParam, sizeof(kSHA256GarbageParam)); | |||
EXPECT_FALSE(EVP_parse_digest_algorithm(&cbs)); | |||
} |
@@ -1,32 +0,0 @@ | |||
/* Copyright (c) 2017, 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_DIGEST_EXTRA_INTERNAL_H | |||
#define OPENSSL_HEADER_DIGEST_EXTRA_INTERNAL_H | |||
#include <openssl/base.h> | |||
#if defined(__cplusplus) | |||
extern "C" { | |||
#endif | |||
const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs); | |||
#if defined(__cplusplus) | |||
} // extern C | |||
#endif | |||
#endif // OPENSSL_HEADER_DIGEST_EXTRA_INTERNAL |
@@ -71,7 +71,6 @@ | |||
#include "internal.h" | |||
#include "../bytestring/internal.h" | |||
#include "../digest_extra/internal.h" | |||
#include "../internal.h" | |||
@@ -201,6 +201,23 @@ OPENSSL_EXPORT size_t EVP_MD_block_size(const EVP_MD *md); | |||
#define EVP_MD_FLAG_DIGALGID_ABSENT 2 | |||
// ASN.1 functions. | |||
// | |||
// These functions allow code to parse and serialize AlgorithmIdentifiers for | |||
// hash functions. | |||
// EVP_parse_digest_algorithm parses an AlgorithmIdentifier structure containing | |||
// a hash function OID (for example, 2.16.840.1.101.3.4.2.1 is SHA-256) and | |||
// advances |cbs|. The parameters field may either be omitted or a NULL. It | |||
// returns the digest function or NULL on error. | |||
OPENSSL_EXPORT const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs); | |||
// EVP_marshal_digest_algorithm marshals |md| as an AlgorithmIdentifier | |||
// structure and appends the result to |cbb|. It returns one on success and zero | |||
// on error. | |||
OPENSSL_EXPORT int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md); | |||
// Deprecated functions. | |||
// EVP_MD_CTX_copy sets |out|, which must /not/ be initialised, to be a copy of | |||