summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2016-09-03 11:39:57 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2016-09-05 09:45:57 +0200
commita852b4b2e1342f043cdd2d2db9f4522984b739a1 (patch)
treec016a71c76f57a9b6c27e5041a1b9d0d33933dff
parent85b7058898a0095334dd2f8ebc964d582f8cff02 (diff)
downloadgnutls-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
-rw-r--r--lib/pk.c59
1 files changed, 46 insertions, 13 deletions
diff --git a/lib/pk.c b/lib/pk.c
index d0cc3ec372..d724d65a9a 100644
--- a/lib/pk.c
+++ b/lib/pk.c
@@ -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