From 2abe135f971aca7a3ecc231d10f96b5fddee078a Mon Sep 17 00:00:00 2001 From: Viktor Tarasov Date: Sat, 7 Mar 2015 21:36:16 +0100 Subject: [PATCH] asn1: re-fix error in EC signature encode helper see comment for https://github.com/OpenSC/OpenSC/commit/8cf99a93726e735e04ed2563f14e315a60a4a859 --- src/libopensc/asn1.c | 30 +++++++++++++++++------------- src/libopensc/asn1.h | 2 +- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index ba4a0a16..1eeb2ef2 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -1865,15 +1865,18 @@ sc_asn1_sig_value_rs_to_sequence(struct sc_context *ctx, unsigned char *in, size int sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx, unsigned char *in, size_t inlen, - unsigned char **buf, size_t *buflen) + unsigned char *buf, size_t buflen) { struct sc_asn1_entry asn1_sig_value[C_ASN1_SIG_VALUE_SIZE]; struct sc_asn1_entry asn1_sig_value_coefficients[C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE]; unsigned char *r, *s; - size_t r_len, s_len, len; + size_t r_len, s_len, halflen = buflen/2; int rv; LOG_FUNC_CALLED(ctx); + if (!buf || !buflen) + LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS); + sc_copy_asn1_entry(c_asn1_sig_value, asn1_sig_value); sc_format_asn1_entry(asn1_sig_value + 0, asn1_sig_value_coefficients, NULL, 0); @@ -1884,21 +1887,22 @@ sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx, unsigned char *in, size rv = sc_asn1_decode(ctx, asn1_sig_value, in, inlen, NULL, NULL); LOG_TEST_RET(ctx, rv, "ASN.1 decoding ECDSA-Sig-Value failed"); - len = r_len > s_len ? r_len : s_len; + if (halflen < r_len || halflen < s_len) { + rv = SC_ERROR_BUFFER_TOO_SMALL; + goto done; + } - *buf = calloc(2 * len, 1); - if (*buf == NULL) - LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); + memset(buf, 0, buflen); + memcpy(buf + (halflen - r_len), r, r_len); + memcpy(buf + (buflen - s_len), s, s_len); - memcpy(*buf + len - r_len, r, r_len); - memcpy(*buf + 2*len - s_len, s, s_len); - *buflen = 2 * len; - - sc_log(ctx, "r(%i): %s", len, sc_dump_hex(*buf, len)); - sc_log(ctx, "s(%i): %s", len, sc_dump_hex(*buf + len, len)); + sc_log(ctx, "r(%i): %s", halflen, sc_dump_hex(buf, halflen)); + sc_log(ctx, "s(%i): %s", halflen, sc_dump_hex(buf + halflen, halflen)); + rv = SC_SUCCESS; +done: free(r); free(s); - LOG_FUNC_RETURN(ctx, SC_SUCCESS); + LOG_FUNC_RETURN(ctx, rv); } diff --git a/src/libopensc/asn1.h b/src/libopensc/asn1.h index 13958845..0fa23e18 100644 --- a/src/libopensc/asn1.h +++ b/src/libopensc/asn1.h @@ -125,7 +125,7 @@ int sc_asn1_sig_value_rs_to_sequence(struct sc_context *ctx, unsigned char **buf, size_t *buflen); int sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx, unsigned char *in, size_t inlen, - unsigned char **buf, size_t *buflen); + unsigned char *buf, size_t buflen); #define SC_ASN1_CLASS_MASK 0x30000000 #define SC_ASN1_UNI 0x00000000 /* Universal */