diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2016-09-03 11:39:57 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-09-05 09:45:57 +0200 |
commit | a852b4b2e1342f043cdd2d2db9f4522984b739a1 (patch) | |
tree | c016a71c76f57a9b6c27e5041a1b9d0d33933dff /lib/pk.c | |
parent | 85b7058898a0095334dd2f8ebc964d582f8cff02 (diff) | |
download | gnutls-a852b4b2e1342f043cdd2d2db9f4522984b739a1.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
Diffstat (limited to 'lib/pk.c')
-rw-r--r-- | lib/pk.c | 59 |
1 files changed, 46 insertions, 13 deletions
@@ -45,7 +45,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(), @@ -55,27 +56,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 |