diff options
Diffstat (limited to 'lib/mpi.c')
-rw-r--r-- | lib/mpi.c | 107 |
1 files changed, 95 insertions, 12 deletions
@@ -153,6 +153,28 @@ _gnutls_mpi_init_scan_nz(bigint_t * ret_mpi, const void *buffer, size_t nbytes) return 0; } +int +_gnutls_mpi_init_scan_le(bigint_t * ret_mpi, const void *buffer, size_t nbytes) +{ + bigint_t r; + int ret; + + ret = _gnutls_mpi_init(&r); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = _gnutls_mpi_scan_le(r, buffer, nbytes); + if (ret < 0) { + gnutls_assert(); + _gnutls_mpi_release(&r); + return ret; + } + + *ret_mpi = r; + + return 0; +} + /* Always has the first bit zero */ int _gnutls_mpi_dprint_lz(const bigint_t a, gnutls_datum_t * dest) { @@ -248,13 +270,43 @@ _gnutls_mpi_dprint_size(const bigint_t a, gnutls_datum_t * dest, return 0; } +/* like _gnutls_mpi_dprint_size, but prints into preallocated byte buffer */ +int +_gnutls_mpi_bprint_size(const bigint_t a, uint8_t *buf, size_t size) +{ + int result; + size_t bytes = 0; + + result = _gnutls_mpi_print(a, NULL, &bytes); + if (result != GNUTLS_E_SHORT_MEMORY_BUFFER) + return gnutls_assert_val(result); + + if (bytes <= size) { + unsigned i; + size_t diff = size - bytes; + + for (i = 0; i < diff; i++) + buf[i] = 0; + result = _gnutls_mpi_print(a, &buf[diff], &bytes); + } else { + result = _gnutls_mpi_print(a, buf, &bytes); + } + + return result; +} + +/* Flags for __gnutls_x509_read_int() and __gnutls_x509_write_int */ +#define GNUTLS_X509_INT_OVERWRITE (1 << 0) +#define GNUTLS_X509_INT_LE (1 << 1) +#define GNUTLS_X509_INT_LZ (1 << 2) /* write only */ + /* this function reads an integer * from asn1 structs. Combines the read and mpi_scan * steps. */ static int __gnutls_x509_read_int(ASN1_TYPE node, const char *value, - bigint_t * ret_mpi, int overwrite) + bigint_t * ret_mpi, unsigned int flags) { int result; uint8_t *tmpstr = NULL; @@ -280,9 +332,14 @@ __gnutls_x509_read_int(ASN1_TYPE node, const char *value, return _gnutls_asn2err(result); } - result = _gnutls_mpi_init_scan(ret_mpi, tmpstr, tmpstr_size); + if (flags & GNUTLS_X509_INT_LE) + result = _gnutls_mpi_init_scan_le(ret_mpi, tmpstr, + tmpstr_size); + else + result = _gnutls_mpi_init_scan(ret_mpi, tmpstr, + tmpstr_size); - if (overwrite) + if (flags & GNUTLS_X509_INT_OVERWRITE) zeroize_key(tmpstr, tmpstr_size); gnutls_free(tmpstr); @@ -298,29 +355,42 @@ int _gnutls_x509_read_int(ASN1_TYPE node, const char *value, bigint_t * ret_mpi) { - return __gnutls_x509_read_int(node, value, ret_mpi, 0); + return __gnutls_x509_read_int(node, value, ret_mpi, + 0); } int _gnutls_x509_read_key_int(ASN1_TYPE node, const char *value, bigint_t * ret_mpi) { - return __gnutls_x509_read_int(node, value, ret_mpi, 1); + return __gnutls_x509_read_int(node, value, ret_mpi, + GNUTLS_X509_INT_OVERWRITE); +} + +int +_gnutls_x509_read_key_int_le(ASN1_TYPE node, const char *value, + bigint_t * ret_mpi) +{ + return __gnutls_x509_read_int(node, value, ret_mpi, + GNUTLS_X509_INT_OVERWRITE | + GNUTLS_X509_INT_LE); } /* Writes the specified integer into the specified node. */ static int __gnutls_x509_write_int(ASN1_TYPE node, const char *value, bigint_t mpi, - int lz, int overwrite) + unsigned int flags) { uint8_t *tmpstr; size_t s_len; int result; s_len = 0; - if (lz) + if (flags & GNUTLS_X509_INT_LZ) result = _gnutls_mpi_print_lz(mpi, NULL, &s_len); + else if (GNUTLS_X509_INT_LE) + result = _gnutls_mpi_print_le(mpi, NULL, &s_len); else result = _gnutls_mpi_print(mpi, NULL, &s_len); @@ -335,8 +405,10 @@ __gnutls_x509_write_int(ASN1_TYPE node, const char *value, bigint_t mpi, return GNUTLS_E_MEMORY_ERROR; } - if (lz) + if (flags & GNUTLS_X509_INT_LZ) result = _gnutls_mpi_print_lz(mpi, tmpstr, &s_len); + else if (GNUTLS_X509_INT_LE) + result = _gnutls_mpi_print_le(mpi, tmpstr, &s_len); else result = _gnutls_mpi_print(mpi, tmpstr, &s_len); @@ -347,8 +419,8 @@ __gnutls_x509_write_int(ASN1_TYPE node, const char *value, bigint_t mpi, } result = asn1_write_value(node, value, tmpstr, s_len); - - if (overwrite) + + if (flags & GNUTLS_X509_INT_OVERWRITE) zeroize_key(tmpstr, s_len); gnutls_free(tmpstr); @@ -365,12 +437,23 @@ int _gnutls_x509_write_int(ASN1_TYPE node, const char *value, bigint_t mpi, int lz) { - return __gnutls_x509_write_int(node, value, mpi, lz, 0); + return __gnutls_x509_write_int(node, value, mpi, + lz ? GNUTLS_X509_INT_LZ : 0); } int _gnutls_x509_write_key_int(ASN1_TYPE node, const char *value, bigint_t mpi, int lz) { - return __gnutls_x509_write_int(node, value, mpi, lz, 1); + return __gnutls_x509_write_int(node, value, mpi, + (lz ? GNUTLS_X509_INT_LZ : 0) | + GNUTLS_X509_INT_OVERWRITE); +} + +int +_gnutls_x509_write_key_int_le(ASN1_TYPE node, const char *value, bigint_t mpi) +{ + return __gnutls_x509_write_int(node, value, mpi, + GNUTLS_X509_INT_OVERWRITE | + GNUTLS_X509_INT_LE); } |