diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2016-09-03 11:39:57 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-09-05 13:08:11 +0200 |
commit | 0c37d19b7ad44b66f11893258bc88aa7fc35b244 (patch) | |
tree | 10bd1b58a7f02cbf6bb73dae5b49395b2a261378 | |
parent | 7f0e27adfcb3cc2a2a65ddd5543c6f2d2b233940 (diff) | |
download | gnutls-0c37d19b7ad44b66f11893258bc88aa7fc35b244.tar.gz |
_gnutls_encode_ber_rs_raw: zero-pad values when necessary
This addresses issue when encoding values obtained via
PKCS#11 which may not be necessarily padded.
Resolves #122
-rw-r--r-- | lib/gnutls_pk.c | 59 |
1 files changed, 46 insertions, 13 deletions
diff --git a/lib/gnutls_pk.c b/lib/gnutls_pk.c index 2b5ad3e0b4..f60b28e61a 100644 --- a/lib/gnutls_pk.c +++ b/lib/gnutls_pk.c @@ -44,7 +44,8 @@ _gnutls_encode_ber_rs_raw(gnutls_datum_t * sig_value, const gnutls_datum_t * s) { ASN1_TYPE sig; - int result; + int result, ret; + uint8_t *tmp = NULL; if ((result = asn1_create_element(_gnutls_get_gnutls_asn(), @@ -54,27 +55,59 @@ _gnutls_encode_ber_rs_raw(gnutls_datum_t * sig_value, return _gnutls_asn2err(result); } - result = asn1_write_value(sig, "r", r->data, r->size); + if (r->data[0] >= 0x80) { + tmp = gnutls_malloc(r->size+1); + if (tmp == NULL) { + ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + goto cleanup; + } + memcpy(&tmp[1], r->data, r->size); + tmp[0] = 0; + result = asn1_write_value(sig, "r", tmp, 1+r->size); + + gnutls_free(tmp); + tmp = NULL; + } else { + result = asn1_write_value(sig, "r", r->data, r->size); + } if (result != ASN1_SUCCESS) { gnutls_assert(); - asn1_delete_structure(&sig); - return _gnutls_asn2err(result); + ret = _gnutls_asn2err(result); + goto cleanup; + } + + if (s->data[0] >= 0x80) { + tmp = gnutls_malloc(s->size+1); + if (tmp == NULL) { + ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + goto cleanup; + } + memcpy(&tmp[1], s->data, s->size); + tmp[0] = 0; + result = asn1_write_value(sig, "s", tmp, 1+s->size); + + gnutls_free(tmp); + tmp = NULL; + } else { + result = asn1_write_value(sig, "s", s->data, s->size); } - result = asn1_write_value(sig, "s", s->data, s->size); if (result != ASN1_SUCCESS) { gnutls_assert(); - asn1_delete_structure(&sig); - return _gnutls_asn2err(result); + ret = _gnutls_asn2err(result); + goto cleanup; } - result = _gnutls_x509_der_encode(sig, "", sig_value, 0); - asn1_delete_structure(&sig); - - if (result < 0) - return gnutls_assert_val(result); + ret = _gnutls_x509_der_encode(sig, "", sig_value, 0); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } - return 0; + ret = 0; + cleanup: + asn1_delete_structure(&sig); + return ret; } int |