diff options
-rw-r--r-- | doc/Makefile.am | 10 | ||||
-rw-r--r-- | doc/manpages/Makefile.am | 5 | ||||
-rw-r--r-- | lib/includes/gnutls/crypto.h | 3 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 7 | ||||
-rw-r--r-- | lib/libgnutls.map | 5 | ||||
-rw-r--r-- | lib/mpi.c | 25 | ||||
-rw-r--r-- | lib/mpi.h | 1 | ||||
-rw-r--r-- | lib/pk.c | 167 | ||||
-rw-r--r-- | lib/pk.h | 11 | ||||
-rw-r--r-- | lib/x509/common.c | 87 | ||||
-rw-r--r-- | lib/x509/common.h | 7 | ||||
-rw-r--r-- | symbols.last | 5 |
12 files changed, 333 insertions, 0 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am index b38b1e84eb..f56ee101a5 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -894,6 +894,8 @@ FUNCS += functions/gnutls_db_set_store_function FUNCS += functions/gnutls_db_set_store_function.short FUNCS += functions/gnutls_decode_ber_digest_info FUNCS += functions/gnutls_decode_ber_digest_info.short +FUNCS += functions/gnutls_decode_gost_rs_value +FUNCS += functions/gnutls_decode_gost_rs_value.short FUNCS += functions/gnutls_decode_rs_value FUNCS += functions/gnutls_decode_rs_value.short FUNCS += functions/gnutls_deinit @@ -974,6 +976,8 @@ FUNCS += functions/gnutls_ecc_curve_list FUNCS += functions/gnutls_ecc_curve_list.short FUNCS += functions/gnutls_encode_ber_digest_info FUNCS += functions/gnutls_encode_ber_digest_info.short +FUNCS += functions/gnutls_encode_gost_rs_value +FUNCS += functions/gnutls_encode_gost_rs_value.short FUNCS += functions/gnutls_encode_rs_value FUNCS += functions/gnutls_encode_rs_value.short FUNCS += functions/gnutls_error_is_fatal @@ -1016,6 +1020,10 @@ FUNCS += functions/gnutls_global_set_mutex FUNCS += functions/gnutls_global_set_mutex.short FUNCS += functions/gnutls_global_set_time_function FUNCS += functions/gnutls_global_set_time_function.short +FUNCS += functions/gnutls_gost_paramset_get_name +FUNCS += functions/gnutls_gost_paramset_get_name.short +FUNCS += functions/gnutls_gost_paramset_get_oid +FUNCS += functions/gnutls_gost_paramset_get_oid.short FUNCS += functions/gnutls_group_get FUNCS += functions/gnutls_group_get.short FUNCS += functions/gnutls_group_get_id @@ -1214,6 +1222,8 @@ FUNCS += functions/gnutls_oid_to_digest FUNCS += functions/gnutls_oid_to_digest.short FUNCS += functions/gnutls_oid_to_ecc_curve FUNCS += functions/gnutls_oid_to_ecc_curve.short +FUNCS += functions/gnutls_oid_to_gost_paramset +FUNCS += functions/gnutls_oid_to_gost_paramset.short FUNCS += functions/gnutls_oid_to_mac FUNCS += functions/gnutls_oid_to_mac.short FUNCS += functions/gnutls_oid_to_pk diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am index 66e92efa4b..5679518a29 100644 --- a/doc/manpages/Makefile.am +++ b/doc/manpages/Makefile.am @@ -242,6 +242,7 @@ APIMANS += gnutls_db_set_remove_function.3 APIMANS += gnutls_db_set_retrieve_function.3 APIMANS += gnutls_db_set_store_function.3 APIMANS += gnutls_decode_ber_digest_info.3 +APIMANS += gnutls_decode_gost_rs_value.3 APIMANS += gnutls_decode_rs_value.3 APIMANS += gnutls_deinit.3 APIMANS += gnutls_dh_get_group.3 @@ -282,6 +283,7 @@ APIMANS += gnutls_ecc_curve_get_pk.3 APIMANS += gnutls_ecc_curve_get_size.3 APIMANS += gnutls_ecc_curve_list.3 APIMANS += gnutls_encode_ber_digest_info.3 +APIMANS += gnutls_encode_gost_rs_value.3 APIMANS += gnutls_encode_rs_value.3 APIMANS += gnutls_error_is_fatal.3 APIMANS += gnutls_error_to_alert.3 @@ -303,6 +305,8 @@ APIMANS += gnutls_global_set_log_level.3 APIMANS += gnutls_global_set_mem_functions.3 APIMANS += gnutls_global_set_mutex.3 APIMANS += gnutls_global_set_time_function.3 +APIMANS += gnutls_gost_paramset_get_name.3 +APIMANS += gnutls_gost_paramset_get_oid.3 APIMANS += gnutls_group_get.3 APIMANS += gnutls_group_get_id.3 APIMANS += gnutls_group_get_name.3 @@ -402,6 +406,7 @@ APIMANS += gnutls_ocsp_status_request_get2.3 APIMANS += gnutls_ocsp_status_request_is_checked.3 APIMANS += gnutls_oid_to_digest.3 APIMANS += gnutls_oid_to_ecc_curve.3 +APIMANS += gnutls_oid_to_gost_paramset.3 APIMANS += gnutls_oid_to_mac.3 APIMANS += gnutls_oid_to_pk.3 APIMANS += gnutls_oid_to_sign.3 diff --git a/lib/includes/gnutls/crypto.h b/lib/includes/gnutls/crypto.h index 947e25caf9..f20d3463bb 100644 --- a/lib/includes/gnutls/crypto.h +++ b/lib/includes/gnutls/crypto.h @@ -247,6 +247,9 @@ gnutls_decode_ber_digest_info(const gnutls_datum_t * info, int gnutls_decode_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t *r, gnutls_datum_t *s); int gnutls_encode_rs_value(gnutls_datum_t * sig_value, const gnutls_datum_t * r, const gnutls_datum_t * s); +int gnutls_encode_gost_rs_value(gnutls_datum_t * sig_value, const gnutls_datum_t * r, const gnutls_datum_t *s); +int gnutls_decode_gost_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t * r, gnutls_datum_t * s); + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 66043925e1..7a0a63188d 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -1180,6 +1180,11 @@ const char * const char *gnutls_sign_get_oid(gnutls_sign_algorithm_t sign) __GNUTLS_CONST__; +const char * + gnutls_gost_paramset_get_name(gnutls_gost_paramset_t param) __GNUTLS_CONST__; +const char * + gnutls_gost_paramset_get_oid(gnutls_gost_paramset_t param) __GNUTLS_CONST__; + size_t gnutls_cipher_get_key_size(gnutls_cipher_algorithm_t algorithm) __GNUTLS_CONST__; size_t @@ -1237,6 +1242,8 @@ gnutls_sign_algorithm_t gnutls_oid_to_sign(const char *oid) __GNUTLS_CONST__; gnutls_ecc_curve_t gnutls_oid_to_ecc_curve(const char *oid) __GNUTLS_CONST__; +gnutls_gost_paramset_t + gnutls_oid_to_gost_paramset(const char *oid) __GNUTLS_CONST__; /* list supported algorithms */ const gnutls_ecc_curve_t * diff --git a/lib/libgnutls.map b/lib/libgnutls.map index f95fe0a846..6d81cf8b9c 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -1221,6 +1221,11 @@ GNUTLS_3_6_3 gnutls_pkcs11_obj_get_ptr; gnutls_session_ticket_send; gnutls_aead_cipher_encryptv; + gnutls_gost_paramset_get_name; + gnutls_gost_paramset_get_oid; + gnutls_oid_to_gost_paramset; + gnutls_decode_gost_rs_value; + gnutls_encode_gost_rs_value; } GNUTLS_3_6_2; GNUTLS_FIPS140_3_4 { @@ -270,6 +270,31 @@ _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) @@ -83,6 +83,7 @@ int _gnutls_mpi_dprint_lz(const bigint_t a, gnutls_datum_t * dest); int _gnutls_mpi_dprint(const bigint_t a, gnutls_datum_t * dest); int _gnutls_mpi_dprint_size(const bigint_t a, gnutls_datum_t * dest, size_t size); +int _gnutls_mpi_bprint_size(const bigint_t a, uint8_t *buf, size_t size); typedef int (*mpi_dprint_func)(const bigint_t a, gnutls_datum_t * dest); @@ -295,6 +295,170 @@ _gnutls_decode_ber_rs_raw(const gnutls_datum_t * sig_value, gnutls_datum_t *r, return 0; } +int +_gnutls_encode_gost_rs(gnutls_datum_t * sig_value, bigint_t r, bigint_t s, + size_t intsize) +{ + uint8_t *data; + int result; + + data = gnutls_malloc(intsize * 2); + if (data == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + if ((result = _gnutls_mpi_bprint_size(s, data, intsize)) < 0) { + gnutls_assert(); + gnutls_free(data); + return result; + } + + if ((result = _gnutls_mpi_bprint_size(r, data + intsize, intsize)) < 0) { + gnutls_assert(); + gnutls_free(data); + return result; + } + + sig_value->data = data; + sig_value->size = intsize * 2; + + return 0; +} + +int +_gnutls_decode_gost_rs(const gnutls_datum_t * sig_value, bigint_t * r, + bigint_t * s) +{ + int ret; + unsigned halfsize = sig_value->size >> 1; + + if (sig_value->size % 2 != 0) { + return gnutls_assert_val(GNUTLS_E_PARSING_ERROR); + } + + ret = _gnutls_mpi_init_scan(s, sig_value->data, halfsize); + if (ret < 0) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + ret = _gnutls_mpi_init_scan(r, sig_value->data + halfsize, halfsize); + if (ret < 0) { + _gnutls_mpi_release(s); + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + } + + return 0; +} + +/** + * gnutls_encode_gost_rs_value: + * @sig_value: will hold a GOST signature according to RFC 4491 section 2.2.2 + * @r: must contain the r value + * @s: must contain the s value + * + * This function will encode the provided r and s values, into binary + * representation according to RFC 4491 section 2.2.2, used for GOST R + * 34.10-2001 (and thus also for GOST R 34.10-2012) signatures. + * + * The output value should be deallocated using gnutls_free(). + * + * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise + * an error code is returned. + * + * Since: 3.6.0 + */ +int gnutls_encode_gost_rs_value(gnutls_datum_t * sig_value, const gnutls_datum_t * r, const gnutls_datum_t *s) +{ + uint8_t *data; + size_t intsize = r->size; + + if (s->size != intsize) { + gnutls_assert(); + return GNUTLS_E_ILLEGAL_PARAMETER; + } + + data = gnutls_malloc(intsize * 2); + if (data == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + memcpy(data, s->data, intsize); + memcpy(data + intsize, r->data, intsize); + + sig_value->data = data; + sig_value->size = intsize * 2; + + return 0; +} + +/** + * gnutls_decode_gost_rs_value: + * @sig_value: will holds a GOST signature according to RFC 4491 section 2.2.2 + * @r: will contain the r value + * @s: will contain the s value + * + * This function will decode the provided @sig_value, into @r and @s elements. + * See RFC 4491 section 2.2.2 for the format of signature value. + * + * The output values may be padded with a zero byte to prevent them + * from being interpreted as negative values. The value + * should be deallocated using gnutls_free(). + * + * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise + * an error code is returned. + * + * Since: 3.6.0 + */ +int gnutls_decode_gost_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t * r, gnutls_datum_t * s) +{ + int ret; + unsigned halfsize = sig_value->size >> 1; + + if (sig_value->size % 2 != 0) + return gnutls_assert_val(GNUTLS_E_PARSING_ERROR); + + ret = _gnutls_set_datum(s, sig_value->data, halfsize); + if (ret != 0) + return gnutls_assert_val(ret); + + ret = _gnutls_set_datum(r, sig_value->data + halfsize, halfsize); + if (ret != 0) { + _gnutls_free_datum(s); + return gnutls_assert_val(ret); + } + + return 0; +} + +gnutls_digest_algorithm_t _gnutls_gost_digest(gnutls_pk_algorithm_t pk) +{ + if (pk == GNUTLS_PK_GOST_01) + return GNUTLS_DIG_GOSTR_94; + else if (pk == GNUTLS_PK_GOST_12_256) + return GNUTLS_DIG_STREEBOG_256; + else if (pk == GNUTLS_PK_GOST_12_512) + return GNUTLS_DIG_STREEBOG_512; + + gnutls_assert(); + + return GNUTLS_DIG_UNKNOWN; +} + +gnutls_pk_algorithm_t _gnutls_digest_gost(gnutls_digest_algorithm_t digest) +{ + if (digest == GNUTLS_DIG_GOSTR_94) + return GNUTLS_PK_GOST_01; + else if (digest == GNUTLS_DIG_STREEBOG_256) + return GNUTLS_PK_GOST_12_256; + else if (digest == GNUTLS_DIG_STREEBOG_512) + return GNUTLS_PK_GOST_12_512; + + gnutls_assert(); + + return GNUTLS_PK_UNKNOWN; +} + /* some generic pk functions */ int _gnutls_pk_params_copy(gnutls_pk_params_st * dst, @@ -972,6 +1136,9 @@ pk_prepare_hash(gnutls_pk_algorithm_t pk, case GNUTLS_PK_DSA: case GNUTLS_PK_ECDSA: case GNUTLS_PK_EDDSA_ED25519: + case GNUTLS_PK_GOST_01: + case GNUTLS_PK_GOST_12_256: + case GNUTLS_PK_GOST_12_512: break; default: gnutls_assert(); @@ -70,6 +70,17 @@ _gnutls_decode_ber_rs_raw(const gnutls_datum_t * sig_value, gnutls_datum_t *r, gnutls_datum_t *s); int +_gnutls_encode_gost_rs(gnutls_datum_t * sig_value, bigint_t r, bigint_t s, + size_t intsize); + +int +_gnutls_decode_gost_rs(const gnutls_datum_t * sig_value, bigint_t * r, + bigint_t * s); + +gnutls_digest_algorithm_t _gnutls_gost_digest(gnutls_pk_algorithm_t pk); +gnutls_pk_algorithm_t _gnutls_digest_gost(gnutls_digest_algorithm_t digest); + +int encode_ber_digest_info(const mac_entry_st * e, const gnutls_datum_t * digest, gnutls_datum_t * output); diff --git a/lib/x509/common.c b/lib/x509/common.c index f4310d7e36..a446186625 100644 --- a/lib/x509/common.c +++ b/lib/x509/common.c @@ -1813,3 +1813,90 @@ int _gnutls_check_if_sorted(gnutls_x509_crt_t * crt, int nr) cleanup: return ret; } + +/** + * gnutls_gost_paramset_get_name: + * @param: is a GOST 28147 param set + * + * Convert a #gnutls_gost_paramset_t value to a string. + * + * Returns: a string that contains the name of the specified GOST param set, + * or %NULL. + * + * Since: 3.6.3 + **/ +const char *gnutls_gost_paramset_get_name(gnutls_gost_paramset_t param) +{ + switch(param) { + case GNUTLS_GOST_PARAMSET_TC26_Z: + return "TC26-Z"; + case GNUTLS_GOST_PARAMSET_CP_A: + return "CryptoPro-A"; + case GNUTLS_GOST_PARAMSET_CP_B: + return "CryptoPro-B"; + case GNUTLS_GOST_PARAMSET_CP_C: + return "CryptoPro-C"; + case GNUTLS_GOST_PARAMSET_CP_D: + return "CryptoPro-D"; + default: + gnutls_assert(); + return "Unknown"; + } +} + +/** + * gnutls_gost_paramset_get_oid: + * @param: is a GOST 28147 param set + * + * Convert a #gnutls_gost_paramset_t value to its object identifier. + * + * Returns: a string that contains the object identifier of the specified GOST + * param set, or %NULL. + * + * Since: 3.6.3 + **/ +const char *gnutls_gost_paramset_get_oid(gnutls_gost_paramset_t param) +{ + switch(param) { + case GNUTLS_GOST_PARAMSET_TC26_Z: + return GOST28147_89_TC26Z_OID; + case GNUTLS_GOST_PARAMSET_CP_A: + return GOST28147_89_CPA_OID; + case GNUTLS_GOST_PARAMSET_CP_B: + return GOST28147_89_CPB_OID; + case GNUTLS_GOST_PARAMSET_CP_C: + return GOST28147_89_CPC_OID; + case GNUTLS_GOST_PARAMSET_CP_D: + return GOST28147_89_CPD_OID; + default: + gnutls_assert(); + return NULL; + } +} + +/** + * gnutls_oid_to_gost_paramset: + * @oid: is an object identifier + * + * Converts a textual object identifier to a #gnutls_gost_paramset_t value. + * + * Returns: a #gnutls_gost_paramset_get_oid of the specified GOST 28147 + * param st, or %GNUTLS_GOST_PARAMSET_UNKNOWN on failure. + * + * Since: 3.6.3 + **/ +gnutls_gost_paramset_t gnutls_oid_to_gost_paramset(const char *oid) +{ + if (!strcmp(oid, GOST28147_89_TC26Z_OID)) + return GNUTLS_GOST_PARAMSET_TC26_Z; + else if (!strcmp(oid, GOST28147_89_CPA_OID)) + return GNUTLS_GOST_PARAMSET_CP_A; + else if (!strcmp(oid, GOST28147_89_CPB_OID)) + return GNUTLS_GOST_PARAMSET_CP_B; + else if (!strcmp(oid, GOST28147_89_CPC_OID)) + return GNUTLS_GOST_PARAMSET_CP_C; + else if (!strcmp(oid, GOST28147_89_CPD_OID)) + return GNUTLS_GOST_PARAMSET_CP_D; + else + return gnutls_assert_val(GNUTLS_GOST_PARAMSET_UNKNOWN); +} diff --git a/lib/x509/common.h b/lib/x509/common.h index d5c368a7b9..637121c2ee 100644 --- a/lib/x509/common.h +++ b/lib/x509/common.h @@ -103,6 +103,13 @@ #define KRB5_PRINCIPAL_OID "1.3.6.1.5.2.2" #define PKIX1_RSA_PSS_MGF1_OID "1.2.840.113549.1.1.8" +#define GOST28147_89_OID "1.2.643.2.2.21" +#define GOST28147_89_TC26Z_OID "1.2.643.7.1.2.5.1.1" +#define GOST28147_89_CPA_OID "1.2.643.2.2.31.1" +#define GOST28147_89_CPB_OID "1.2.643.2.2.31.2" +#define GOST28147_89_CPC_OID "1.2.643.2.2.31.3" +#define GOST28147_89_CPD_OID "1.2.643.2.2.31.4" + #define ASN1_NULL "\x05\x00" #define ASN1_NULL_SIZE 2 diff --git a/symbols.last b/symbols.last index c5b94fdd1e..9995f36d08 100644 --- a/symbols.last +++ b/symbols.last @@ -144,6 +144,7 @@ gnutls_db_set_remove_function@GNUTLS_3_4 gnutls_db_set_retrieve_function@GNUTLS_3_4 gnutls_db_set_store_function@GNUTLS_3_4 gnutls_decode_ber_digest_info@GNUTLS_3_4 +gnutls_decode_gost_rs_value@GNUTLS_3_6_3 gnutls_decode_rs_value@GNUTLS_3_6_0 gnutls_deinit@GNUTLS_3_4 gnutls_dh_get_group@GNUTLS_3_4 @@ -184,6 +185,7 @@ gnutls_ecc_curve_get_pk@GNUTLS_3_4 gnutls_ecc_curve_get_size@GNUTLS_3_4 gnutls_ecc_curve_list@GNUTLS_3_4 gnutls_encode_ber_digest_info@GNUTLS_3_4 +gnutls_encode_gost_rs_value@GNUTLS_3_6_3 gnutls_encode_rs_value@GNUTLS_3_6_0 gnutls_error_is_fatal@GNUTLS_3_4 gnutls_error_to_alert@GNUTLS_3_4 @@ -218,6 +220,8 @@ gnutls_global_set_log_level@GNUTLS_3_4 gnutls_global_set_mem_functions@GNUTLS_3_4 gnutls_global_set_mutex@GNUTLS_3_4 gnutls_global_set_time_function@GNUTLS_3_4 +gnutls_gost_paramset_get_name@GNUTLS_3_6_3 +gnutls_gost_paramset_get_oid@GNUTLS_3_6_3 gnutls_group_get@GNUTLS_3_6_0 gnutls_group_get_id@GNUTLS_3_6_0 gnutls_group_get_name@GNUTLS_3_6_0 @@ -318,6 +322,7 @@ gnutls_ocsp_status_request_get@GNUTLS_3_4 gnutls_ocsp_status_request_is_checked@GNUTLS_3_4 gnutls_oid_to_digest@GNUTLS_3_4 gnutls_oid_to_ecc_curve@GNUTLS_3_4 +gnutls_oid_to_gost_paramset@GNUTLS_3_6_3 gnutls_oid_to_mac@GNUTLS_3_4 gnutls_oid_to_pk@GNUTLS_3_4 gnutls_oid_to_sign@GNUTLS_3_4 |