diff options
author | Armin Burgmeier <armin@arbur.net> | 2014-09-17 18:59:29 -0400 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2014-09-24 10:06:31 +0200 |
commit | 967092ce312760be0ae40067c0ffc6f2d7b095f1 (patch) | |
tree | 90258ea0c05caab6b5be23dec660573245028efe /lib | |
parent | c770406513dce298d2efac05d63723f10db7d16e (diff) | |
download | gnutls-967092ce312760be0ae40067c0ffc6f2d7b095f1.tar.gz |
Add functions to obtain X.509 keys and certificates from certificate credentials
Signed-off-by: Armin Burgmeier <armin@arbur.net>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gnutls_x509.c | 96 | ||||
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 8 | ||||
-rw-r--r-- | lib/libgnutls.map | 2 |
3 files changed, 106 insertions, 0 deletions
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c index 70e999e736..5309f25c84 100644 --- a/lib/gnutls_x509.c +++ b/lib/gnutls_x509.c @@ -1140,6 +1140,102 @@ gnutls_certificate_set_x509_key(gnutls_certificate_credentials_t res, } /** + * gnutls_certificate_get_x509_key: + * @res: is a #gnutls_certificate_credentials_t structure. + * @index: The index of the key to obtain. + * @key: Location to store the key. + * + * Obtains a X.509 private key that has been stored in @res with one of + * gnutls_certificate_set_x509_key(), gnutls_certificate_set_key(), + * gnutls_certificate_set_x509_key_file(), + * gnutls_certificate_set_x509_key_file2(), + * gnutls_certificate_set_x509_key_mem(), or + * gnutls_certificate_set_x509_key_mem2(). The returned key must be deallocated + * with gnutls_x509_privkey_deinit() when no longer needed. + * + * If there is no key with the given index, + * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned. If the key with the + * given index is not a X.509 key, %GNUTLS_E_INVALID_REQUEST is returned. + * + * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code. + * + * Since: 3.4.0 + */ +int +gnutls_certificate_get_x509_key(gnutls_certificate_credentials_t res, + int index, + gnutls_x509_privkey_t *key) +{ + if (index >= res->ncerts) { + gnutls_assert(); + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + } + + return gnutls_privkey_export_x509(res->pkey[index], key); +} + +/** + * gnutls_certificate_get_x509_crt: + * @res: is a #gnutls_certificate_credentials_t structure. + * @index: The index of the certificate list to obtain. + * @crt_list: Where to store the certificate list. + * @key: Will hold the number of certificates. + * + * Obtains a X.509 certificate list that has been stored in @res with one of + * gnutls_certificate_set_x509_key(), gnutls_certificate_set_key(), + * gnutls_certificate_set_x509_key_file(), + * gnutls_certificate_set_x509_key_file2(), + * gnutls_certificate_set_x509_key_mem(), or + * gnutls_certificate_set_x509_key_mem2(). Each certificate in the returned + * certificate list must be deallocated with gnutls_x509_crt_deinit(), and the + * list itself must be freed with gnutls_free(). + * + * If there is no certificate with the given index, + * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned. If the certificate + * with the given index is not a X.509 certificate, %GNUTLS_E_INVALID_REQUEST + * is returned. + * + * Returns: %GNUTLS_E_SUCCESS (0) on success, or a negative error code. + * + * Since: 3.4.0 + */ +int +gnutls_certificate_get_x509_crt(gnutls_certificate_credentials_t res, + int index, + gnutls_x509_crt_t **crt_list, + int *crt_list_size) +{ + int ret, i; + + if (index >= res->ncerts) { + gnutls_assert(); + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + } + + *crt_list_size = res->certs[index].cert_list_length; + *crt_list = gnutls_malloc( + res->certs[index].cert_list_length * sizeof (gnutls_x509_crt_t)); + if (*crt_list == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + for (i = 0; i < res->certs[index].cert_list_length; ++i) { + ret = gnutls_pcert_export_x509(&res->certs[index].cert_list[i], crt_list[i]); + if (ret < 0) { + while (i--) + gnutls_x509_crt_deinit(*crt_list[i]); + gnutls_free(*crt_list); + *crt_list = NULL; + + return gnutls_assert_val(ret); + } + } + + return 0; +} + +/** * gnutls_certificate_set_key: * @res: is a #gnutls_certificate_credentials_t structure. * @names: is an array of DNS name of the certificate (NULL if none) diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index f47fa6f967..a03e1f9d72 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -1434,6 +1434,14 @@ int gnutls_certificate_set_x509_crl(gnutls_certificate_credentials_t res, gnutls_x509_crl_t * crl_list, int crl_list_size); +int gnutls_certificate_get_x509_key(gnutls_certificate_credentials_t res, + int index, + gnutls_x509_privkey_t *key); +int gnutls_certificate_get_x509_crt(gnutls_certificate_credentials_t res, + int index, + gnutls_x509_crt_t **crt_list, + int *crt_list_size); + /* OCSP status request extension, RFC 6066 */ typedef int (*gnutls_status_request_ocsp_func) (gnutls_session_t session, void *ptr, gnutls_datum_t * ocsp_response); diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 02f4485d66..062a55bd46 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -1014,6 +1014,8 @@ GNUTLS_3_1_0 { gnutls_openpgp_crt_check_hostname2; gnutls_certificate_verify_peers; gnutls_certificate_get_verify_flags; + gnutls_certificate_get_x509_key; + gnutls_certificate_get_x509_crt; gnutls_credentials_get; gnutls_x509_crl_iter_crt_serial; gnutls_x509_crl_iter_deinit; |