diff options
author | David Benjamin <davidben@chromium.org> | 2016-01-03 11:57:37 +0300 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2016-02-17 02:51:09 +0300 |
commit | 2f6410ba4e8f610db59e56c5802bfbeb3f57ecf2 (patch) | |
tree | c785fba44a156286390fce8f64554e8d69b91dd5 /include/openssl/ec_key.h | |
parent | 666973b8e9b6befe63249e51ff6b63e7605c605d (diff) |
Rewrite ECPrivateKey serialization.
Functions which lose object reuse and need auditing:
- d2i_ECParameters
- d2i_ECPrivateKey
This adds a handful of bytestring-based APIs to handle EC key
serialization. Deprecate all the old serialization APIs. Notes:
- An EC_KEY has additional state that controls its encoding, enc_flags
and conv_form. conv_form is left alone, but enc_flags in the new API
is an explicit parameter.
- d2i_ECPrivateKey interpreted its T** argument unlike nearly every
other d2i function. This is an explicit EC_GROUP parameter in the new
function.
- The new specified curve code is much stricter and should parse enough
to uniquely identify the curve.
- I've not bothered with a new version of i2d_ECParameters. It just
writes an OID. This may change later when decoupling from the giant
OID table.
- Likewise, I've not bothered with new APIs for the public key since the
EC_POINT APIs should suffice.
- Previously, d2i_ECPrivateKey would not call EC_KEY_check_key and it
was possible for the imported public and private key to mismatch. It
now calls it.
BUG=499653
Change-Id: I30b4dd2841ae76c56ab0e1808360b2628dee0615
Reviewed-on: https://boringssl-review.googlesource.com/6859
Reviewed-by: Adam Langley <agl@google.com>
Diffstat (limited to 'include/openssl/ec_key.h')
-rw-r--r-- | include/openssl/ec_key.h | 124 |
1 files changed, 78 insertions, 46 deletions
diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index da96508c..27423558 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -177,52 +177,26 @@ OPENSSL_EXPORT int EC_KEY_generate_key(EC_KEY *key); /* Serialisation. */ -/* d2i_ECPrivateKey parses an ASN.1, DER-encoded, private key from |len| bytes - * at |*inp|. If |out_key| is not NULL then, on exit, a pointer to the result - * is in |*out_key|. If |*out_key| is already non-NULL on entry then the result - * is written directly into |*out_key|, otherwise a fresh |EC_KEY| is - * allocated. However, one should not depend on writing into |*out_key| because - * this behaviour is likely to change in the future. On successful exit, |*inp| - * is advanced past the DER structure. It returns the result or NULL on - * error. */ -OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey(EC_KEY **out_key, const uint8_t **inp, - long len); - -/* i2d_ECPrivateKey marshals an EC private key from |key| to an ASN.1, DER - * structure. 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. */ -OPENSSL_EXPORT int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp); - -/* d2i_ECParameters parses an ASN.1, DER-encoded, set of EC parameters from - * |len| bytes at |*inp|. If |out_key| is not NULL then, on exit, a pointer to - * the result is in |*out_key|. If |*out_key| is already non-NULL on entry then - * the result is written directly into |*out_key|, otherwise a fresh |EC_KEY| - * is allocated. However, one should not depend on writing into |*out_key| - * because this behaviour is likely to change in the future. On successful - * exit, |*inp| is advanced past the DER structure. It returns the result or - * NULL on error. */ -OPENSSL_EXPORT EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, - long len); - -/* i2d_ECParameters marshals EC parameters from |key| to an ASN.1, DER - * structure. 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. */ -OPENSSL_EXPORT int i2d_ECParameters(const EC_KEY *key, uint8_t **outp); - -/* o2i_ECPublicKey parses an EC point from |len| bytes at |*inp| into - * |*out_key|. Note that this differs from the d2i format in that |*out_key| - * must be non-NULL with a group set. On successful exit, |*inp| is advanced by - * |len| bytes. It returns |*out_key| or NULL on error. */ -OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp, - long len); - -/* i2o_ECPublicKey marshals an EC point from |key|. 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. */ -OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); +/* EC_KEY_parse_private_key parses a DER-encoded ECPrivateKey structure (RFC + * 5915) from |cbs| and advances |cbs|. It returns a newly-allocated |EC_KEY| or + * NULL on error. If |group| is non-null, the parameters field of the + * ECPrivateKey may be omitted (but must match |group| if present). Otherwise, + * the parameters field is required. */ +OPENSSL_EXPORT EC_KEY *EC_KEY_parse_private_key(CBS *cbs, + const EC_GROUP *group); + +/* EC_KEY_marshal_private_key marshals |key| as a DER-encoded ECPrivateKey + * structure (RFC 5915) and appends the result to |cbb|. It returns one on + * success and zero on failure. |enc_flags| is a combination of |EC_PKEY_*| + * values and controls whether corresponding fields are omitted. */ +OPENSSL_EXPORT int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key, + unsigned enc_flags); + +/* EC_KEY_parse_parameters parses a DER-encoded ECParameters structure (RFC + * 5480) from |cbs| and advances |cbs|. It returns a newly-allocated |EC_GROUP| + * or NULL on error. It supports the namedCurve and specifiedCurve options, but + * use of specifiedCurve is deprecated. */ +OPENSSL_EXPORT EC_GROUP *EC_KEY_parse_parameters(CBS *cbs); /* ex_data functions. @@ -276,6 +250,64 @@ struct ecdsa_method_st { /* EC_KEY_set_asn1_flag does nothing. */ OPENSSL_EXPORT void EC_KEY_set_asn1_flag(EC_KEY *key, int flag); +/* d2i_ECPrivateKey parses an ASN.1, DER-encoded, private key from |len| bytes + * at |*inp|. If |out_key| is not NULL then, on exit, a pointer to the result + * is in |*out_key|. Note that, even if |*out_key| is already non-NULL on entry, + * it * will not be written to. Rather, a fresh |EC_KEY| is allocated and the + * previous * one is freed. On successful exit, |*inp| is advanced past the DER + * structure. It returns the result or NULL on error. + * + * On input, if |*out_key| is non-NULL and has a group configured, the + * parameters field may be omitted but must match that group if present. + * + * Use |EC_KEY_parse_private_key| instead. */ +OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey(EC_KEY **out_key, const uint8_t **inp, + long len); + +/* i2d_ECPrivateKey marshals an EC private key from |key| to an ASN.1, DER + * structure. 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. + * + * Use |EC_KEY_marshal_private_key| instead. */ +OPENSSL_EXPORT int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp); + +/* d2i_ECParameters parses an ASN.1, DER-encoded, set of EC parameters from + * |len| bytes at |*inp|. If |out_key| is not NULL then, on exit, a pointer to + * the result is in |*out_key|. Note that, even if |*out_key| is already + * non-NULL on entry, it will not be written to. Rather, a fresh |EC_KEY| is + * allocated and the previous one is freed. On successful exit, |*inp| is + * advanced past the DER structure. It returns the result or NULL on error. + * + * Use EC_KEY_parse_parameters instead. */ +OPENSSL_EXPORT EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, + long len); + +/* i2d_ECParameters marshals EC parameters from |key| to an ASN.1, DER + * structure. 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. + * + * Use |OBJ_nid2cbb| and |EC_GROUP_get_curve_name| instead. */ +OPENSSL_EXPORT int i2d_ECParameters(const EC_KEY *key, uint8_t **outp); + +/* o2i_ECPublicKey parses an EC point from |len| bytes at |*inp| into + * |*out_key|. Note that this differs from the d2i format in that |*out_key| + * must be non-NULL with a group set. On successful exit, |*inp| is advanced by + * |len| bytes. It returns |*out_key| or NULL on error. + * + * Use |EC_POINT_oct2point| instead. */ +OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp, + long len); + +/* i2o_ECPublicKey marshals an EC point from |key|. 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. + * + * Use |EC_POINT_point2cbb| instead. */ +OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); + #if defined(__cplusplus) } /* extern C */ |