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 13:08:11 +0200
commit0c37d19b7ad44b66f11893258bc88aa7fc35b244 (patch)
tree10bd1b58a7f02cbf6bb73dae5b49395b2a261378
parent7f0e27adfcb3cc2a2a65ddd5543c6f2d2b233940 (diff)
downloadgnutls-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.c59
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