Преглед на файлове

Decouple PKCS#12 hash lookup from the OID table.

This isn't strictly necessary for Chromium yet, but we already have a
decoupled version of hash algorithm parsing available. For now, don't
export it but eventually we may wish to use it for OCSP.

BUG=54

Change-Id: If460d38d48bd47a2b4a853779f210c0cf7ee236b
Reviewed-on: https://boringssl-review.googlesource.com/14211
Reviewed-by: Steven Valdez <svaldez@chromium.org>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@chromium.org>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
kris/onging/CECPQ3_patch15
David Benjamin преди 7 години
committed by CQ bot account: commit-bot@chromium.org
родител
ревизия
3cb047e56c
променени са 5 файла, в които са добавени 66 реда и са изтрити 24 реда
  1. +44
    -5
      crypto/digest/digests.c
  2. +2
    -0
      crypto/digest/internal.h
  3. +2
    -0
      crypto/err/digest.errordata
  4. +16
    -19
      crypto/pkcs8/pkcs8.c
  5. +2
    -0
      include/openssl/digest.h

+ 44
- 5
crypto/digest/digests.c Целия файл

@@ -60,6 +60,7 @@
#include <string.h>

#include <openssl/asn1.h>
#include <openssl/bytestring.h>
#include <openssl/md4.h>
#include <openssl/md5.h>
#include <openssl/nid.h>
@@ -328,20 +329,58 @@ static const struct {
{ {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04}, 9, EVP_sha224 },
};

static const EVP_MD *cbs_to_md(const CBS *cbs) {
for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) {
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 NULL;
}

const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *obj) {
/* Handle objects with no corresponding OID. */
if (obj->nid != NID_undef) {
return EVP_get_digestbynid(obj->nid);
}

for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) {
if (obj->length == kMDOIDs[i].oid_len &&
memcmp(obj->data, kMDOIDs[i].oid, obj->length) == 0) {
return kMDOIDs[i].md_func();
CBS cbs;
CBS_init(&cbs, obj->data, obj->length);
return cbs_to_md(&cbs);
}

const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs) {
CBS algorithm, oid;
if (!CBS_get_asn1(cbs, &algorithm, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) {
OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_DECODE_ERROR);
return NULL;
}

const EVP_MD *ret = cbs_to_md(&oid);
if (ret == NULL) {
OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_UNKNOWN_HASH);
return NULL;
}

/* The parameters, if present, must be NULL. Historically, whether the NULL
* was included or omitted was not well-specified. When parsing an
* AlgorithmIdentifier, we allow both. (Note this code is not used when
* verifying RSASSA-PKCS1-v1_5 signatures.) */
if (CBS_len(&algorithm) > 0) {
CBS param;
if (!CBS_get_asn1(&algorithm, &param, CBS_ASN1_NULL) ||
CBS_len(&param) != 0 ||
CBS_len(&algorithm) != 0) {
OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_DECODE_ERROR);
return NULL;
}
}

return NULL;
return ret;
}

const EVP_MD *EVP_get_digestbyname(const char *name) {


+ 2
- 0
crypto/digest/internal.h Целия файл

@@ -104,6 +104,8 @@ struct evp_md_pctx_ops {
EVP_PKEY_CTX* (*dup) (EVP_PKEY_CTX *pctx);
};

const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs);


#if defined(__cplusplus)
} /* extern C */


+ 2
- 0
crypto/err/digest.errordata Целия файл

@@ -1 +1,3 @@
DIGEST,101,DECODE_ERROR
DIGEST,100,INPUT_NOT_INITIALIZED
DIGEST,102,UNKNOWN_HASH

+ 16
- 19
crypto/pkcs8/pkcs8.c Целия файл

@@ -74,6 +74,7 @@
#include "internal.h"
#include "../internal.h"
#include "../bytestring/internal.h"
#include "../digest/internal.h"


#define PKCS12_KEY_ID 1
@@ -1032,25 +1033,25 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,

/* Verify the MAC. */
{
CBS mac, hash_type_seq, hash_oid, salt, expected_mac;
uint64_t iterations;
int hash_nid;
const EVP_MD *md;
uint8_t hmac_key[EVP_MAX_MD_SIZE];
uint8_t hmac[EVP_MAX_MD_SIZE];
unsigned hmac_len;
CBS mac, salt, expected_mac;
if (!CBS_get_asn1(&mac_data, &mac, CBS_ASN1_SEQUENCE)) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}

if (!CBS_get_asn1(&mac_data, &mac, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1(&mac, &hash_type_seq, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1(&hash_type_seq, &hash_oid, CBS_ASN1_OBJECT) ||
!CBS_get_asn1(&mac, &expected_mac, CBS_ASN1_OCTETSTRING) ||
const EVP_MD *md = EVP_parse_digest_algorithm(&mac);
if (md == NULL) {
goto err;
}

if (!CBS_get_asn1(&mac, &expected_mac, CBS_ASN1_OCTETSTRING) ||
!CBS_get_asn1(&mac_data, &salt, CBS_ASN1_OCTETSTRING)) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}

/* The iteration count is optional and the default is one. */
iterations = 1;
uint64_t iterations = 1;
if (CBS_len(&mac_data) > 0) {
if (!CBS_get_asn1_uint64(&mac_data, &iterations) ||
iterations > UINT_MAX) {
@@ -1059,19 +1060,15 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
}
}

hash_nid = OBJ_cbs2nid(&hash_oid);
if (hash_nid == NID_undef ||
(md = EVP_get_digestbynid(hash_nid)) == NULL) {
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_HASH);
goto err;
}

uint8_t hmac_key[EVP_MAX_MD_SIZE];
if (!pkcs12_key_gen_raw(ctx.password, ctx.password_len, CBS_data(&salt),
CBS_len(&salt), PKCS12_MAC_ID, iterations,
EVP_MD_size(md), hmac_key, md)) {
goto err;
}

uint8_t hmac[EVP_MAX_MD_SIZE];
unsigned hmac_len;
if (NULL == HMAC(md, hmac_key, EVP_MD_size(md), CBS_data(&authsafes),
CBS_len(&authsafes), hmac, &hmac_len)) {
goto err;


+ 2
- 0
include/openssl/digest.h Целия файл

@@ -283,5 +283,7 @@ using ScopedEVP_MD_CTX =
#endif

#define DIGEST_R_INPUT_NOT_INITIALIZED 100
#define DIGEST_R_DECODE_ERROR 101
#define DIGEST_R_UNKNOWN_HASH 102

#endif /* OPENSSL_HEADER_DIGEST_H */

Зареждане…
Отказ
Запис