diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-04-04 15:46:45 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-04-06 12:57:07 +0200 |
commit | 28e723ca0b830abe3b36f401b001d74359a6c200 (patch) | |
tree | 1b4377c31316d7725fa5822c5216e39526d3a930 | |
parent | 071e6df609b60e82d2d12344464e112e6dafebfc (diff) | |
download | gnutls-28e723ca0b830abe3b36f401b001d74359a6c200.tar.gz |
Added helper functions to parse the inhibit anyPolicy X.509 extension
That introduces:
* gnutls_x509_ext_export_inhibit_anypolicy
* gnutls_x509_ext_import_inhibit_anypolicy
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r-- | lib/includes/gnutls/x509-ext.h | 5 | ||||
-rw-r--r-- | lib/includes/gnutls/x509.h | 2 | ||||
-rw-r--r-- | lib/libgnutls.map | 2 | ||||
-rw-r--r-- | lib/x509/mpi.c | 35 | ||||
-rw-r--r-- | lib/x509/x509_ext.c | 77 | ||||
-rw-r--r-- | lib/x509/x509_int.h | 8 |
6 files changed, 126 insertions, 3 deletions
diff --git a/lib/includes/gnutls/x509-ext.h b/lib/includes/gnutls/x509-ext.h index 79a37ebab2..8180c75bb0 100644 --- a/lib/includes/gnutls/x509-ext.h +++ b/lib/includes/gnutls/x509-ext.h @@ -162,6 +162,11 @@ int gnutls_x509_ext_import_key_usage(const gnutls_datum_t * ext, int gnutls_x509_ext_export_key_usage(unsigned int key_usage, gnutls_datum_t * ext); +int gnutls_x509_ext_import_inhibit_anypolicy(const gnutls_datum_t * ext, + unsigned int *skipcerts); +int gnutls_x509_ext_export_inhibit_anypolicy(unsigned int skipcerts, + gnutls_datum_t * ext); + int gnutls_x509_ext_import_proxy(const gnutls_datum_t * ext, int *pathlen, char **policyLanguage, char **policy, size_t * sizeof_policy); diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h index e2a0b2b89b..ddfe9f4a58 100644 --- a/lib/includes/gnutls/x509.h +++ b/lib/includes/gnutls/x509.h @@ -107,6 +107,8 @@ extern "C" { #define GNUTLS_X509EXT_OID_PROXY_CRT_INFO "1.3.6.1.5.5.7.1.14" #define GNUTLS_X509EXT_OID_TLSFEATURES "1.3.6.1.5.5.7.1.24" +#define GNUTLS_X509_OID_POLICY_ANY "2.5.29.54" + /* Certificate handling functions. */ diff --git a/lib/libgnutls.map b/lib/libgnutls.map index adf4902774..727d57bc7e 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -1136,6 +1136,8 @@ GNUTLS_3_4 gnutls_idna_reverse_map; gnutls_x509_crt_set_flags; gnutls_x509_crt_check_ip; + gnutls_x509_ext_import_inhibit_anypolicy; + gnutls_x509_ext_export_inhibit_anypolicy; local: *; }; diff --git a/lib/x509/mpi.c b/lib/x509/mpi.c index 4852941763..2e7cdc2802 100644 --- a/lib/x509/mpi.c +++ b/lib/x509/mpi.c @@ -67,6 +67,41 @@ int _gnutls_x509_read_der_int(uint8_t * der, int dersize, bigint_t * out) } +int _gnutls_x509_read_der_uint(uint8_t * der, int dersize, unsigned int *out) +{ + int result; + ASN1_TYPE spk = ASN1_TYPE_EMPTY; + + /* == INTEGER */ + if ((result = asn1_create_element + (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey", + &spk)) != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + result = _asn1_strict_der_decode(&spk, der, dersize, NULL); + + if (result != ASN1_SUCCESS) { + gnutls_assert(); + asn1_delete_structure(&spk); + return _gnutls_asn2err(result); + } + + /* Read Y */ + + if ((result = _gnutls_x509_read_uint(spk, "", out)) < 0) { + gnutls_assert(); + asn1_delete_structure(&spk); + return _gnutls_asn2err(result); + } + + asn1_delete_structure(&spk); + + return 0; + +} + /* Extracts DSA and RSA parameters from a certificate. */ diff --git a/lib/x509/x509_ext.c b/lib/x509/x509_ext.c index cf504a85c6..ca190d36ed 100644 --- a/lib/x509/x509_ext.c +++ b/lib/x509/x509_ext.c @@ -1181,6 +1181,83 @@ int gnutls_x509_ext_export_key_usage(unsigned int usage, gnutls_datum_t * ext) } /** + * gnutls_x509_ext_import_inhibit_anypolicy: + * @ext: the DER encoded extension data + * @skipcerts: will hold the number of certificates after which anypolicy is no longer acceptable. + * + * This function will return certificate's value of SkipCerts, + * by reading the DER data of the Inhibit anyPolicy X.509 extension (2.5.29.54). + * + * The @skipcerts value is the number of additional certificates that + * may appear in the path before the anyPolicy (%GNUTLS_X509_OID_POLICY_ANY) + * is no longer acceptable. + * + * Returns: zero, or a negative error code in case of + * parsing error. If the certificate does not contain the Inhibit anyPolicy + * extension %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be + * returned. + * + * Since: 3.6.0 + **/ +int gnutls_x509_ext_import_inhibit_anypolicy(const gnutls_datum_t * ext, + unsigned int *skipcerts) +{ + int ret; + + ret = _gnutls_x509_read_der_uint(ext->data, ext->size, skipcerts); + if (ret < 0) { + gnutls_assert(); + } + + return ret; +} + +/** + * gnutls_x509_ext_export_inhibit_anypolicy: + * @skipcerts: number of certificates after which anypolicy is no longer acceptable. + * @ext: The DER-encoded extension data; must be freed using gnutls_free(). + * + * This function will convert the @skipcerts value to a DER + * encoded Inhibit AnyPolicy PKIX extension. The @ext data will be allocated using + * gnutls_malloc(). + * + * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a + * negative error value. + * + * Since: 3.6.0 + **/ +int gnutls_x509_ext_export_inhibit_anypolicy(unsigned int skipcerts, gnutls_datum_t * ext) +{ + ASN1_TYPE c2 = ASN1_TYPE_EMPTY; + int result, ret; + + result = asn1_create_element(_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey", &c2); + if (result != ASN1_SUCCESS) { + gnutls_assert(); + return _gnutls_asn2err(result); + } + + ret = _gnutls_x509_write_uint32(c2, "", skipcerts); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + ret = _gnutls_x509_der_encode(c2, "", ext, 0); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + ret = 0; + + cleanup: + asn1_delete_structure(&c2); + + return ret; +} + +/** * gnutls_x509_ext_import_private_key_usage_period: * @ext: the DER encoded extension data * @activation: Will hold the activation time diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h index 62007f48c1..6e2b4dd58f 100644 --- a/lib/x509/x509_int.h +++ b/lib/x509/x509_int.h @@ -335,20 +335,22 @@ int _gnutls_x509_read_uint(ASN1_TYPE node, const char *value, unsigned int *ret); int _gnutls_x509_read_der_int(uint8_t * der, int dersize, bigint_t * out); +int _gnutls_x509_read_der_uint(uint8_t * der, int dersize, unsigned int *out); int _gnutls_x509_read_int(ASN1_TYPE node, const char *value, bigint_t * ret_mpi); int _gnutls_x509_write_int(ASN1_TYPE node, const char *value, bigint_t mpi, int lz); +int _gnutls_x509_write_uint32(ASN1_TYPE node, const char *value, + uint32_t num); + + int _gnutls_x509_read_key_int(ASN1_TYPE node, const char *value, bigint_t * ret_mpi); int _gnutls_x509_write_key_int(ASN1_TYPE node, const char *value, bigint_t mpi, int lz); -int _gnutls_x509_write_uint32(ASN1_TYPE node, const char *value, - uint32_t num); - int _gnutls_x509_write_sig_params(ASN1_TYPE dst, const char *dst_name, gnutls_pk_algorithm_t pk_algorithm, gnutls_digest_algorithm_t, unsigned legacy); |