diff options
author | David Makepeace <david.p.makepeace@oracle.com> | 2019-06-03 14:58:54 +1000 |
---|---|---|
committer | Pauli <paul.dale@oracle.com> | 2019-07-12 06:26:46 +1000 |
commit | 54846b7c6ef5718f507def9d192628133f97fe20 (patch) | |
tree | 4d6810f0dda7442ec72619737c0724322e024ace /crypto/dsa | |
parent | 35e264c03232c7843733caa80f8e16bef7e2e829 (diff) | |
download | openssl-54846b7c6ef5718f507def9d192628133f97fe20.tar.gz |
Add simple ASN.1 utils for DSA signature DER.
Adds simple utility functions to allow both the default and fips providers to
encode and decode DSA-Sig-Value and ECDSA-Sig-Value (DSA_SIG and ECDSA_SIG
structures) to/from ASN.1 DER without requiring those providers to have a
dependency on the asn1 module.
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9111)
Diffstat (limited to 'crypto/dsa')
-rw-r--r-- | crypto/dsa/dsa_asn1.c | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c index acf80c651a..1c7e8c86bd 100644 --- a/crypto/dsa/dsa_asn1.c +++ b/crypto/dsa/dsa_asn1.c @@ -13,13 +13,7 @@ #include <openssl/asn1.h> #include <openssl/asn1t.h> #include <openssl/rand.h> - -ASN1_SEQUENCE(DSA_SIG) = { - ASN1_SIMPLE(DSA_SIG, r, CBIGNUM), - ASN1_SIMPLE(DSA_SIG, s, CBIGNUM) -} static_ASN1_SEQUENCE_END(DSA_SIG) - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(DSA_SIG, DSA_SIG, DSA_SIG) +#include "internal/asn1_dsa.h" DSA_SIG *DSA_SIG_new(void) { @@ -38,6 +32,62 @@ void DSA_SIG_free(DSA_SIG *sig) OPENSSL_free(sig); } +DSA_SIG *d2i_DSA_SIG(DSA_SIG **psig, const unsigned char **ppin, long len) +{ + DSA_SIG *sig; + + if (len < 0) + return NULL; + if (psig != NULL && *psig != NULL) { + sig = *psig; + } else { + sig = DSA_SIG_new(); + if (sig == NULL) + return NULL; + } + if (sig->r == NULL) + sig->r = BN_new(); + if (sig->s == NULL) + sig->s = BN_new(); + if (decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) { + if (psig == NULL || *psig == NULL) + DSA_SIG_free(sig); + return NULL; + } + if (psig != NULL && *psig == NULL) + *psig = sig; + return sig; +} + +int i2d_DSA_SIG(const DSA_SIG *sig, unsigned char **ppout) +{ + unsigned char *buf = NULL; + unsigned char *tmp; + unsigned char **pp = NULL; + size_t len; + size_t encoded_len; + + if (ppout != NULL && *ppout == NULL) { + if ((len = encode_der_dsa_sig(sig->r, sig->s, NULL, SIZE_MAX)) == 0) + return -1; + buf = OPENSSL_malloc(len); + if (buf == NULL) + return -1; + tmp = buf; + pp = &tmp; + } else { + len = SIZE_MAX; + pp = ppout; + } + if ((encoded_len = encode_der_dsa_sig(sig->r, sig->s, pp, len)) == 0) { + OPENSSL_free(buf); + return -1; + } + if (buf != NULL) + *ppout = buf; + return (int)encoded_len; +} + void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) { if (pr != NULL) |