Export EVP_parse_digest_algorithm and add EVP_marshal_digest_algorithm.
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>
This commit is contained in:
parent
3a18bf0474
commit
42e93b6cf5
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user