diff options
author | David Benjamin <davidben@chromium.org> | 2016-01-03 11:57:37 +0300 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2016-02-16 22:40:53 +0300 |
commit | bd42603943c76ee127fd0e3c7872b60de806f214 (patch) | |
tree | ae14f71ac2bc836b3e95a756dba35017085ba070 /crypto | |
parent | 375124b1622e112fbd4584e806030eb7476904c5 (diff) |
Add a convenience function for i2d compatibility wrappers.
An i2d compatibility function is rather long, so add CBB_finish_i2d for
part of it. It takes a CBB as input so only a 'marshal' function is
needed, rather than a 'to_bytes' one.
Also replace the *inp d2i update pattern with a slightly shorter one.
Change-Id: Ibb41059c9532f6a8ce33460890cc1afe26adc97c
Reviewed-on: https://boringssl-review.googlesource.com/6868
Reviewed-by: Adam Langley <agl@google.com>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/bytestring/CMakeLists.txt | 1 | ||||
-rw-r--r-- | crypto/bytestring/asn1_compat.c | 51 | ||||
-rw-r--r-- | crypto/bytestring/internal.h | 9 | ||||
-rw-r--r-- | crypto/ecdsa/ecdsa_asn1.c | 26 | ||||
-rw-r--r-- | crypto/rsa/rsa_asn1.c | 51 |
5 files changed, 78 insertions, 60 deletions
diff --git a/crypto/bytestring/CMakeLists.txt b/crypto/bytestring/CMakeLists.txt index 33d3c217..362e702f 100644 --- a/crypto/bytestring/CMakeLists.txt +++ b/crypto/bytestring/CMakeLists.txt @@ -5,6 +5,7 @@ add_library( OBJECT + asn1_compat.c ber.c cbs.c cbb.c diff --git a/crypto/bytestring/asn1_compat.c b/crypto/bytestring/asn1_compat.c new file mode 100644 index 00000000..b17d2d12 --- /dev/null +++ b/crypto/bytestring/asn1_compat.c @@ -0,0 +1,51 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + + +#include <openssl/bytestring.h> + +#include <assert.h> +#include <limits.h> +#include <string.h> + +#include <openssl/mem.h> + +#include "internal.h" + + +int CBB_finish_i2d(CBB *cbb, uint8_t **outp) { + assert(cbb->base->can_resize); + + uint8_t *der; + size_t der_len; + if (!CBB_finish(cbb, &der, &der_len)) { + CBB_cleanup(cbb); + return -1; + } + if (der_len > INT_MAX) { + OPENSSL_free(der); + return -1; + } + if (outp != NULL) { + if (*outp == NULL) { + *outp = der; + der = NULL; + } else { + memcpy(*outp, der, der_len); + *outp += der_len; + } + } + OPENSSL_free(der); + return (int)der_len; +} diff --git a/crypto/bytestring/internal.h b/crypto/bytestring/internal.h index f4f4b9cd..2fed4139 100644 --- a/crypto/bytestring/internal.h +++ b/crypto/bytestring/internal.h @@ -58,6 +58,15 @@ OPENSSL_EXPORT int CBS_get_asn1_implicit_string(CBS *in, CBS *out, unsigned outer_tag, unsigned inner_tag); +/* CBB_finish_i2d calls |CBB_finish| on |cbb| which must have been initialized + * with |CBB_init|. If |outp| is not NULL then 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. On + * error, it calls |CBB_cleanup| on |cbb|. + * + * This function may be used to help implement legacy i2d ASN.1 functions. */ +int CBB_finish_i2d(CBB *cbb, uint8_t **outp); + #if defined(__cplusplus) } /* extern C */ diff --git a/crypto/ecdsa/ecdsa_asn1.c b/crypto/ecdsa/ecdsa_asn1.c index 61f5d623..3a47257a 100644 --- a/crypto/ecdsa/ecdsa_asn1.c +++ b/crypto/ecdsa/ecdsa_asn1.c @@ -61,6 +61,7 @@ #include <openssl/ec_key.h> #include <openssl/mem.h> +#include "../bytestring/internal.h" #include "../ec/internal.h" @@ -211,30 +212,15 @@ ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, long len) { ECDSA_SIG_free(*out); *out = ret; } - *inp += (size_t)len - CBS_len(&cbs); + *inp = CBS_data(&cbs); return ret; } int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp) { - uint8_t *der; - size_t der_len; - if (!ECDSA_SIG_to_bytes(&der, &der_len, sig)) { - return -1; - } - if (der_len > INT_MAX) { - OPENSSL_PUT_ERROR(ECDSA, ERR_R_OVERFLOW); - OPENSSL_free(der); + CBB cbb; + if (!CBB_init(&cbb, 0) || + !ECDSA_SIG_marshal(&cbb, sig)) { return -1; } - if (outp != NULL) { - if (*outp == NULL) { - *outp = der; - der = NULL; - } else { - memcpy(*outp, der, der_len); - *outp += der_len; - } - } - OPENSSL_free(der); - return (int)der_len; + return CBB_finish_i2d(&cbb, outp); } diff --git a/crypto/rsa/rsa_asn1.c b/crypto/rsa/rsa_asn1.c index 2970717f..83bae4d5 100644 --- a/crypto/rsa/rsa_asn1.c +++ b/crypto/rsa/rsa_asn1.c @@ -67,6 +67,7 @@ #include <openssl/mem.h> #include "internal.h" +#include "../bytestring/internal.h" static int parse_integer_buggy(CBS *cbs, BIGNUM **out, int buggy) { @@ -379,32 +380,17 @@ RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len) { RSA_free(*out); *out = ret; } - *inp += (size_t)len - CBS_len(&cbs); + *inp = CBS_data(&cbs); return ret; } int i2d_RSAPublicKey(const RSA *in, uint8_t **outp) { - uint8_t *der; - size_t der_len; - if (!RSA_public_key_to_bytes(&der, &der_len, in)) { - return -1; - } - if (der_len > INT_MAX) { - OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); - OPENSSL_free(der); + CBB cbb; + if (!CBB_init(&cbb, 0) || + !RSA_marshal_public_key(&cbb, in)) { return -1; } - if (outp != NULL) { - if (*outp == NULL) { - *outp = der; - der = NULL; - } else { - memcpy(*outp, der, der_len); - *outp += der_len; - } - } - OPENSSL_free(der); - return (int)der_len; + return CBB_finish_i2d(&cbb, outp); } RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len) { @@ -421,32 +407,17 @@ RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len) { RSA_free(*out); *out = ret; } - *inp += (size_t)len - CBS_len(&cbs); + *inp = CBS_data(&cbs); return ret; } int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp) { - uint8_t *der; - size_t der_len; - if (!RSA_private_key_to_bytes(&der, &der_len, in)) { - return -1; - } - if (der_len > INT_MAX) { - OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); - OPENSSL_free(der); + CBB cbb; + if (!CBB_init(&cbb, 0) || + !RSA_marshal_private_key(&cbb, in)) { return -1; } - if (outp != NULL) { - if (*outp == NULL) { - *outp = der; - der = NULL; - } else { - memcpy(*outp, der, der_len); - *outp += der_len; - } - } - OPENSSL_free(der); - return (int)der_len; + return CBB_finish_i2d(&cbb, outp); } ASN1_SEQUENCE(RSA_PSS_PARAMS) = { |