diff options
Diffstat (limited to 'libextra')
-rw-r--r-- | libextra/Makefile.am | 4 | ||||
-rw-r--r-- | libextra/auth_srp.c | 1 | ||||
-rw-r--r-- | libextra/auth_srp_passwd.c | 1 | ||||
-rw-r--r-- | libextra/auth_srp_rsa.c | 1 | ||||
-rw-r--r-- | libextra/auth_srp_sb64.c | 1 | ||||
-rw-r--r-- | libextra/ext_srp.c | 1 | ||||
-rw-r--r-- | libextra/gnutls_extra.c | 1 | ||||
-rw-r--r-- | libextra/gnutls_openpgp.c | 1 | ||||
-rw-r--r-- | libextra/gnutls_openssl.c | 3 | ||||
-rw-r--r-- | libextra/gnutls_srp.c | 1 | ||||
-rw-r--r-- | libextra/openpgp/compat.c | 1 | ||||
-rw-r--r-- | libextra/openpgp/extras.c | 1 | ||||
-rw-r--r-- | libextra/openpgp/openpgp.c | 5 | ||||
-rw-r--r-- | libextra/openpgp/privkey.c | 3 | ||||
-rw-r--r-- | libextra/openpgp/verify.c | 1 | ||||
-rw-r--r-- | libextra/openpgp/xml.c | 1 | ||||
-rw-r--r-- | libextra/openssl_compat.c | 796 | ||||
-rw-r--r-- | libextra/openssl_compat.h | 33 |
18 files changed, 850 insertions, 6 deletions
diff --git a/libextra/Makefile.am b/libextra/Makefile.am index 0db520f996..844b9f2c34 100644 --- a/libextra/Makefile.am +++ b/libextra/Makefile.am @@ -12,7 +12,7 @@ else endif EXTRA_DIST = ext_srp.h gnutls_srp.h libgnutls-extra.vers \ - auth_srp.h auth_srp_passwd.h \ + auth_srp.h auth_srp_passwd.h openssl_compat.h \ gnutls-extra-api.tex gnutls_extra.h libgnutls-extra-config.in \ libgnutls-extra.m4 lzoconf.h minilzo.h @@ -22,7 +22,7 @@ lib_LTLIBRARIES = libgnutls-extra.la libgnutls-openssl.la libgnutls_openssl_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) -libgnutls_openssl_la_SOURCES = gnutls_openssl.c +libgnutls_openssl_la_SOURCES = gnutls_openssl.c openssl_compat.c libgnutls_openssl_la_LIBADD = \ ../lib/libgnutls.la diff --git a/libextra/auth_srp.c b/libextra/auth_srp.c index 169949b270..17fe1d28b2 100644 --- a/libextra/auth_srp.c +++ b/libextra/auth_srp.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2001,2002,2003 Nikos Mavroyanopoulos + * Copyright (C) 2004 Free Software Foundation * * This file is part of GNUTLS. * diff --git a/libextra/auth_srp_passwd.c b/libextra/auth_srp_passwd.c index 67cdaf1732..580cc7f438 100644 --- a/libextra/auth_srp_passwd.c +++ b/libextra/auth_srp_passwd.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2001,2003 Nikos Mavroyanopoulos + * Copyright (C) 2004 Free Software Foundation * * This file is part of GNUTLS. * diff --git a/libextra/auth_srp_rsa.c b/libextra/auth_srp_rsa.c index bd5a26df86..561465d71f 100644 --- a/libextra/auth_srp_rsa.c +++ b/libextra/auth_srp_rsa.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2001,2002,2003 Nikos Mavroyanopoulos + * Copyright (C) 2004 Free Software Foundation * * This file is part of GNUTLS. * diff --git a/libextra/auth_srp_sb64.c b/libextra/auth_srp_sb64.c index 9011ec1843..db8edb65b7 100644 --- a/libextra/auth_srp_sb64.c +++ b/libextra/auth_srp_sb64.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2001,2002 Nikos Mavroyanopoulos <nmav@hellug.gr> + * Copyright (C) 2004 Free Software Foundation * * This file is part of GNUTLS. * diff --git a/libextra/ext_srp.c b/libextra/ext_srp.c index a9460a1e7d..2624b965b1 100644 --- a/libextra/ext_srp.c +++ b/libextra/ext_srp.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2001,2002 Nikos Mavroyanopoulos + * Copyright (C) 2004 Free Software Foundation * * This file is part of GNUTLS. * diff --git a/libextra/gnutls_extra.c b/libextra/gnutls_extra.c index b4a8c78576..00c99b2c7e 100644 --- a/libextra/gnutls_extra.c +++ b/libextra/gnutls_extra.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2001 Nikos Mavroyanopoulos + * Copyright (C) 2004 Free Software Foundation * * This file is part of GNUTLS. * diff --git a/libextra/gnutls_openpgp.c b/libextra/gnutls_openpgp.c index 86c2daffe3..4ba3061bcb 100644 --- a/libextra/gnutls_openpgp.c +++ b/libextra/gnutls_openpgp.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2002,2003 Timo Schulz <twoaday@freakmail.de> + * Copyright (C) 2004 Free Software Foundation * * This file is part of GNUTLS. * diff --git a/libextra/gnutls_openssl.c b/libextra/gnutls_openssl.c index b7ecaebb9e..31155e18eb 100644 --- a/libextra/gnutls_openssl.c +++ b/libextra/gnutls_openssl.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2002 Andrew McDonald <andrew@mcdonald.org.uk> + * Copyright (C) 2004 Free Software Foundation * * GNUTLS-EXTRA is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -19,7 +20,7 @@ #include <config.h> #include <gnutls/gnutls.h> -#include <gnutls/compat8.h> +#include <openssl_compat.h> #include <gcrypt.h> #include <stdio.h> #include <stdlib.h> diff --git a/libextra/gnutls_srp.c b/libextra/gnutls_srp.c index e80602b118..2befd82c12 100644 --- a/libextra/gnutls_srp.c +++ b/libextra/gnutls_srp.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2001,2003 Nikos Mavroyanopoulos + * Copyright (C) 2004 Free Software Foundation * * This file is part of GNUTLS. * diff --git a/libextra/openpgp/compat.c b/libextra/openpgp/compat.c index 4faef21985..963efad620 100644 --- a/libextra/openpgp/compat.c +++ b/libextra/openpgp/compat.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2002 Timo Schulz * Portions Copyright (C) 2003 Nikos Mavroyanopoulos + * Copyright 2004 Free Software Foundation * * This file is part of GNUTLS-EXTRA. * diff --git a/libextra/openpgp/extras.c b/libextra/openpgp/extras.c index 48a36ccb7f..1de1b2eb8b 100644 --- a/libextra/openpgp/extras.c +++ b/libextra/openpgp/extras.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2003 Nikos Mavroyanopoulos + * Copyright 2004 Free Software Foundation * * This file is part of GNUTLS-EXTRA. * diff --git a/libextra/openpgp/openpgp.c b/libextra/openpgp/openpgp.c index 22a28a9461..5ebdab7625 100644 --- a/libextra/openpgp/openpgp.c +++ b/libextra/openpgp/openpgp.c @@ -1,6 +1,7 @@ /* - * Copyright (C) 2002 Timo Schulz - * Portions Copyright (C) 2003 Nikos Mavroyanopoulos + * Copyright (C) 2002 Timo Schulz + * Portions Copyright (C) 2003 Nikos Mavroyanopoulos + * Copyright 2004 Free Software Foundation * * This file is part of GNUTLS. * diff --git a/libextra/openpgp/privkey.c b/libextra/openpgp/privkey.c index 51a315fa82..0331ad1bf5 100644 --- a/libextra/openpgp/privkey.c +++ b/libextra/openpgp/privkey.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2003 Nikos Mavroyanopoulos + * Copyright (C) 2003 Nikos Mavroyanopoulos + * Copyright 2004 Free Software Foundation * * This file is part of GNUTLS. * diff --git a/libextra/openpgp/verify.c b/libextra/openpgp/verify.c index 481c558222..7472b4e353 100644 --- a/libextra/openpgp/verify.c +++ b/libextra/openpgp/verify.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2002 Timo Schulz * Portions Copyright (C) 2003 Nikos Mavroyanopoulos + * Copyright 2004 Free Software Foundation * * This file is part of GNUTLS-EXTRA. * diff --git a/libextra/openpgp/xml.c b/libextra/openpgp/xml.c index aacad0830d..d95e10e85a 100644 --- a/libextra/openpgp/xml.c +++ b/libextra/openpgp/xml.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2002 Timo Schulz <twoaday@freakmail.de> * Portions Copyright 2003 Nikos Mavroyanopoulos <nmav@gnutls.org> + * Copyright 2004 Free Software Foundation * * This file is part of GNUTLS. * diff --git a/libextra/openssl_compat.c b/libextra/openssl_compat.c new file mode 100644 index 0000000000..247cad1bdf --- /dev/null +++ b/libextra/openssl_compat.c @@ -0,0 +1,796 @@ +/* + * Copyright (C) 2002,2003 Nikos Mavroyanopoulos + * Copyright (C) 2004 Free Software Foundation + * + * This file is part of GNUTLS. + * + * The GNUTLS library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* This file includes all functions that were in the 0.5.x and 0.8.x + * gnutls API. They are now implemented over the new certificate parsing + * API. + */ + +#include <gnutls_global.h> +#include <gnutls_errors.h> +#include <string.h> /* memset */ +#include <x509/dn.h> +#include <libtasn1.h> +#include <gnutls/x509.h> +#include <openssl_compat.h> + +/** + * gnutls_x509_extract_dn - This function parses an RDN sequence + * @idn: should contain a DER encoded RDN sequence + * @rdn: a pointer to a structure to hold the name + * + * This function will return the name of the given RDN sequence. + * The name will be returned as a gnutls_x509_dn structure. + * Returns a negative error code in case of an error. + * + **/ +int gnutls_x509_extract_dn(const gnutls_datum * idn, gnutls_x509_dn * rdn) +{ + ASN1_TYPE dn = ASN1_TYPE_EMPTY; + int result; + size_t len; + + if ((result = + asn1_create_element(_gnutls_get_pkix(), + "PKIX1.Name", &dn + )) != ASN1_SUCCESS) { + return _gnutls_asn2err(result); + } + + result = asn1_der_decoding(&dn, idn->data, idn->size, NULL); + if (result != ASN1_SUCCESS) { + /* couldn't decode DER */ + asn1_delete_structure(&dn); + return _gnutls_asn2err(result); + } + + memset( rdn, 0, sizeof(gnutls_x509_dn)); + + len = sizeof(rdn->country); + _gnutls_x509_parse_dn_oid( dn, "", GNUTLS_OID_X520_COUNTRY_NAME, 0, 0, rdn->country, &len); + + len = sizeof(rdn->organization); + _gnutls_x509_parse_dn_oid( dn, "", GNUTLS_OID_X520_ORGANIZATION_NAME, 0, 0, rdn->organization, &len); + + len = sizeof(rdn->organizational_unit_name); + _gnutls_x509_parse_dn_oid( dn, "", GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, 0, rdn->organizational_unit_name, &len); + + len = sizeof(rdn->common_name); + _gnutls_x509_parse_dn_oid( dn, "", GNUTLS_OID_X520_COMMON_NAME, 0, 0, rdn->common_name, &len); + + len = sizeof(rdn->locality_name); + _gnutls_x509_parse_dn_oid( dn, "", GNUTLS_OID_X520_LOCALITY_NAME, 0, 0, rdn->locality_name, &len); + + len = sizeof(rdn->state_or_province_name); + _gnutls_x509_parse_dn_oid( dn, "", GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0, 0, rdn->state_or_province_name, &len); + + len = sizeof(rdn->email); + _gnutls_x509_parse_dn_oid( dn, "", GNUTLS_OID_PKCS9_EMAIL, 0, 0, rdn->email, &len); + + asn1_delete_structure(&dn); + + return 0; +} + +/** + * gnutls_x509_extract_certificate_dn - This function returns the certificate's distinguished name + * @cert: should contain an X.509 DER encoded certificate + * @ret: a pointer to a structure to hold the peer's name + * + * This function will return the name of the certificate holder. The name is gnutls_x509_dn structure and + * is a obtained by the peer's certificate. If the certificate send by the + * peer is invalid, or in any other failure this function returns error. + * Returns a negative error code in case of an error. + * + **/ +int gnutls_x509_extract_certificate_dn(const gnutls_datum * cert, + gnutls_x509_dn * ret) +{ + gnutls_x509_crt xcert; + int result; + size_t len; + + result = gnutls_x509_crt_init( &xcert); + if (result < 0) return result; + + result = gnutls_x509_crt_import( xcert, cert, GNUTLS_X509_FMT_DER); + if (result < 0) { + gnutls_x509_crt_deinit( xcert); + return result; + } + + len = sizeof( ret->country); + gnutls_x509_crt_get_dn_by_oid( xcert, GNUTLS_OID_X520_COUNTRY_NAME, 0, 0, + ret->country, &len); + + len = sizeof( ret->organization); + gnutls_x509_crt_get_dn_by_oid( xcert, GNUTLS_OID_X520_ORGANIZATION_NAME, 0, 0, + ret->organization, &len); + + len = sizeof( ret->organizational_unit_name); + gnutls_x509_crt_get_dn_by_oid( xcert, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, 0, + ret->organizational_unit_name, &len); + + len = sizeof( ret->common_name); + gnutls_x509_crt_get_dn_by_oid( xcert, GNUTLS_OID_X520_COMMON_NAME, 0, 0, + ret->common_name, &len); + + len = sizeof( ret->locality_name); + gnutls_x509_crt_get_dn_by_oid( xcert, GNUTLS_OID_X520_LOCALITY_NAME, 0, 0, + ret->locality_name, &len); + + len = sizeof( ret->state_or_province_name); + gnutls_x509_crt_get_dn_by_oid( xcert, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0, 0, + ret->state_or_province_name, &len); + + len = sizeof( ret->email); + gnutls_x509_crt_get_dn_by_oid( xcert, GNUTLS_OID_PKCS9_EMAIL, 0, 0, + ret->email, &len); + + gnutls_x509_crt_deinit( xcert); + + return 0; +} + +/** + * gnutls_x509_extract_certificate_issuer_dn - This function returns the certificate's issuer distinguished name + * @cert: should contain an X.509 DER encoded certificate + * @ret: a pointer to a structure to hold the issuer's name + * + * This function will return the name of the issuer stated in the certificate. The name is a gnutls_x509_dn structure and + * is a obtained by the peer's certificate. If the certificate send by the + * peer is invalid, or in any other failure this function returns error. + * Returns a negative error code in case of an error. + * + **/ +int gnutls_x509_extract_certificate_issuer_dn(const gnutls_datum * cert, + gnutls_x509_dn * ret) +{ + gnutls_x509_crt xcert; + int result; + size_t len; + + result = gnutls_x509_crt_init( &xcert); + if (result < 0) return result; + + result = gnutls_x509_crt_import( xcert, cert, GNUTLS_X509_FMT_DER); + if (result < 0) { + gnutls_x509_crt_deinit( xcert); + return result; + } + + len = sizeof( ret->country); + gnutls_x509_crt_get_issuer_dn_by_oid( xcert, GNUTLS_OID_X520_COUNTRY_NAME, 0, 0, + ret->country, &len); + + len = sizeof( ret->organization); + gnutls_x509_crt_get_issuer_dn_by_oid( xcert, GNUTLS_OID_X520_ORGANIZATION_NAME, 0, 0, + ret->organization, &len); + + len = sizeof( ret->organizational_unit_name); + gnutls_x509_crt_get_issuer_dn_by_oid( xcert, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, 0, + ret->organizational_unit_name, &len); + + len = sizeof( ret->common_name); + gnutls_x509_crt_get_issuer_dn_by_oid( xcert, GNUTLS_OID_X520_COMMON_NAME, 0, 0, + ret->common_name, &len); + + len = sizeof( ret->locality_name); + gnutls_x509_crt_get_issuer_dn_by_oid( xcert, GNUTLS_OID_X520_LOCALITY_NAME, 0, 0, + ret->locality_name, &len); + + len = sizeof( ret->state_or_province_name); + gnutls_x509_crt_get_issuer_dn_by_oid( xcert, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0, 0, + ret->state_or_province_name, &len); + + len = sizeof( ret->email); + gnutls_x509_crt_get_issuer_dn_by_oid( xcert, GNUTLS_OID_PKCS9_EMAIL, 0, 0, + ret->email, &len); + + gnutls_x509_crt_deinit( xcert); + + return 0; +} + + +/** + * gnutls_x509_extract_certificate_subject_alt_name - This function returns the certificate's alternative name, if any + * @cert: should contain an X.509 DER encoded certificate + * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.) + * @ret: is the place where the alternative name will be copied to + * @ret_size: holds the size of ret. + * + * This function will return the alternative names, contained in the + * given certificate. + * + * This is specified in X509v3 Certificate Extensions. + * GNUTLS will return the Alternative name, or a negative + * error code. + * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if ret_size is not enough to hold the alternative + * name, or the type of alternative name if everything was ok. The type is + * one of the enumerated GNUTLS_X509_SUBJECT_ALT_NAME. + * + * If the certificate does not have an Alternative name with the specified + * sequence number then returns GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + * + **/ +int gnutls_x509_extract_certificate_subject_alt_name(const gnutls_datum * cert, int seq, char *ret, int *ret_size) +{ + gnutls_x509_crt xcert; + int result; + size_t size = *ret_size; + + result = gnutls_x509_crt_init( &xcert); + if (result < 0) return result; + + result = gnutls_x509_crt_import( xcert, cert, GNUTLS_X509_FMT_DER); + if (result < 0) { + gnutls_x509_crt_deinit( xcert); + return result; + } + + result = gnutls_x509_crt_get_subject_alt_name( xcert, seq, ret, &size, NULL); + *ret_size = size; + + gnutls_x509_crt_deinit( xcert); + + return result; +} + +/** + * gnutls_x509_extract_certificate_ca_status - This function returns the certificate CA status + * @cert: should contain an X.509 DER encoded certificate + * + * This function will return certificates CA status, by reading the + * basicConstraints X.509 extension. If the certificate is a CA a positive + * value will be returned, or zero if the certificate does not have + * CA flag set. + * + * A negative value may be returned in case of parsing error. + * If the certificate does not contain the basicConstraints extension + * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. + * + **/ +int gnutls_x509_extract_certificate_ca_status(const gnutls_datum * cert) +{ + gnutls_x509_crt xcert; + int result; + + result = gnutls_x509_crt_init( &xcert); + if (result < 0) return result; + + result = gnutls_x509_crt_import( xcert, cert, GNUTLS_X509_FMT_DER); + if (result < 0) { + gnutls_x509_crt_deinit( xcert); + return result; + } + + result = gnutls_x509_crt_get_ca_status( xcert, NULL); + + gnutls_x509_crt_deinit( xcert); + + return result; +} + +/** + * gnutls_x509_extract_certificate_activation_time - This function returns the peer's certificate activation time + * @cert: should contain an X.509 DER encoded certificate + * + * This function will return the certificate's activation time in UNIX time + * (ie seconds since 00:00:00 UTC January 1, 1970). + * Returns a (time_t) -1 in case of an error. + * + **/ +time_t gnutls_x509_extract_certificate_activation_time(const + gnutls_datum * + cert) +{ + gnutls_x509_crt xcert; + time_t result; + + result = gnutls_x509_crt_init( &xcert); + if (result < 0) return result; + + result = gnutls_x509_crt_import( xcert, cert, GNUTLS_X509_FMT_DER); + if (result < 0) { + gnutls_x509_crt_deinit( xcert); + return result; + } + + result = gnutls_x509_crt_get_activation_time( xcert); + + gnutls_x509_crt_deinit( xcert); + + return result; +} + +/** + * gnutls_x509_extract_certificate_expiration_time - This function returns the certificate's expiration time + * @cert: should contain an X.509 DER encoded certificate + * + * This function will return the certificate's expiration time in UNIX time + * (ie seconds since 00:00:00 UTC January 1, 1970). + * Returns a (time_t) -1 in case of an error. + * + **/ +time_t gnutls_x509_extract_certificate_expiration_time(const + gnutls_datum * + cert) +{ + gnutls_x509_crt xcert; + time_t result; + + result = gnutls_x509_crt_init( &xcert); + if (result < 0) return result; + + result = gnutls_x509_crt_import( xcert, cert, GNUTLS_X509_FMT_DER); + if (result < 0) { + gnutls_x509_crt_deinit( xcert); + return result; + } + + result = gnutls_x509_crt_get_expiration_time( xcert); + + gnutls_x509_crt_deinit( xcert); + + return result; +} + +/** + * gnutls_x509_extract_certificate_version - This function returns the certificate's version + * @cert: is an X.509 DER encoded certificate + * + * This function will return the X.509 certificate's version (1, 2, 3). This is obtained by the X509 Certificate + * Version field. Returns a negative value in case of an error. + * + **/ +int gnutls_x509_extract_certificate_version(const gnutls_datum * cert) +{ + gnutls_x509_crt xcert; + int result; + + result = gnutls_x509_crt_init( &xcert); + if (result < 0) return result; + + result = gnutls_x509_crt_import( xcert, cert, GNUTLS_X509_FMT_DER); + if (result < 0) { + gnutls_x509_crt_deinit( xcert); + return result; + } + + result = gnutls_x509_crt_get_version( xcert); + + gnutls_x509_crt_deinit( xcert); + + return result; + +} + +/** + * gnutls_x509_extract_certificate_serial - This function returns the certificate's serial number + * @cert: is an X.509 DER encoded certificate + * @result: The place where the serial number will be copied + * @result_size: Holds the size of the result field. + * + * This function will return the X.509 certificate's serial number. + * This is obtained by the X509 Certificate serialNumber + * field. Serial is not always a 32 or 64bit number. Some CAs use + * large serial numbers, thus it may be wise to handle it as something + * opaque. + * Returns a negative value in case of an error. + * + **/ +int gnutls_x509_extract_certificate_serial(const gnutls_datum * cert, char* result, int* result_size) +{ + gnutls_x509_crt xcert; + size_t size = *result_size; + int ret; + + ret = gnutls_x509_crt_init( &xcert); + if (ret < 0) return ret; + + ret = gnutls_x509_crt_import( xcert, cert, GNUTLS_X509_FMT_DER); + if (ret < 0) { + gnutls_x509_crt_deinit( xcert); + return ret; + } + + ret = gnutls_x509_crt_get_serial( xcert, result, &size); + *result_size = size; + + gnutls_x509_crt_deinit( xcert); + + return ret; +} + + +/** + * gnutls_x509_extract_certificate_pk_algorithm - This function returns the certificate's PublicKey algorithm + * @cert: is a DER encoded X.509 certificate + * @bits: if bits is non null it will hold the size of the parameters' in bits + * + * This function will return the public key algorithm of an X.509 + * certificate. + * + * If bits is non null, it should have enough size to hold the parameters + * size in bits. For RSA the bits returned is the modulus. + * For DSA the bits returned are of the public + * exponent. + * + * Returns a member of the gnutls_pk_algorithm enumeration on success, + * or a negative value on error. + * + **/ +int gnutls_x509_extract_certificate_pk_algorithm( const gnutls_datum * cert, int* bits) +{ + gnutls_x509_crt xcert; + int result; + + result = gnutls_x509_crt_init( &xcert); + if (result < 0) return result; + + result = gnutls_x509_crt_import( xcert, cert, GNUTLS_X509_FMT_DER); + if (result < 0) { + gnutls_x509_crt_deinit( xcert); + return result; + } + + result = gnutls_x509_crt_get_pk_algorithm( xcert, bits); + + gnutls_x509_crt_deinit( xcert); + + return result; +} + + +/** + * gnutls_x509_extract_certificate_dn_string - This function returns the certificate's distinguished name + * @cert: should contain an X.509 DER encoded certificate + * @buf: a pointer to a structure to hold the peer's name + * @sizeof_buf: holds the size of 'buf' + * @issuer: if non zero, then extract the name of the issuer, instead of the holder + * + * This function will copy the name of the certificate holder in the provided buffer. The name + * will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. + * + * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, + * and 0 on success. + * + **/ +int gnutls_x509_extract_certificate_dn_string(char *buf, unsigned int sizeof_buf, + const gnutls_datum * cert, int issuer) +{ + gnutls_x509_crt xcert; + int result; + + result = gnutls_x509_crt_init( &xcert); + if (result < 0) return result; + + result = gnutls_x509_crt_import( xcert, cert, GNUTLS_X509_FMT_DER); + if (result < 0) { + gnutls_x509_crt_deinit( xcert); + return result; + } + + if (!issuer) + result = gnutls_x509_crt_get_dn( xcert, buf, &sizeof_buf); + else + result = gnutls_x509_crt_get_issuer_dn( xcert, buf, &sizeof_buf); + + gnutls_x509_crt_deinit( xcert); + + return result; +} + +/** + * gnutls_x509_verify_certificate - This function verifies given certificate list + * @cert_list: is the certificate list to be verified + * @cert_list_length: holds the number of certificate in cert_list + * @CA_list: is the CA list which will be used in verification + * @CA_list_length: holds the number of CA certificate in CA_list + * @CRL_list: not used + * @CRL_list_length: not used + * + * This function will try to verify the given certificate list and return its status (TRUSTED, EXPIRED etc.). + * The return value (status) should be one or more of the gnutls_certificate_status + * enumerated elements bitwise or'd. Note that expiration and activation dates are not checked + * by this function, you should check them using the appropriate functions. + * + * This function understands the basicConstraints (2.5.29.19) PKIX extension. + * This means that only a certificate authority can sign a certificate. + * + * However you must also check the peer's name in order to check if the verified certificate belongs to the + * actual peer. + * + * The return value (status) should be one or more of the gnutls_certificate_status + * enumerated elements bitwise or'd. + * + * GNUTLS_CERT_INVALID\: the peer's certificate is not valid. + * + * GNUTLS_CERT_REVOKED\: the certificate has been revoked. + * + * A negative error code is returned in case of an error. + * GNUTLS_E_NO_CERTIFICATE_FOUND is returned to indicate that + * no certificate was sent by the peer. + * + * + **/ +int gnutls_x509_verify_certificate( const gnutls_datum* cert_list, int cert_list_length, + const gnutls_datum * CA_list, int CA_list_length, + const gnutls_datum* CRL_list, int CRL_list_length) +{ + unsigned int verify; + gnutls_x509_crt *peer_certificate_list = NULL; + gnutls_x509_crt *ca_certificate_list = NULL; + gnutls_x509_crl *crl_list = NULL; + int peer_certificate_list_size=0, i, x, ret; + int ca_certificate_list_size=0, crl_list_size=0; + + if (cert_list == NULL || cert_list_length == 0) + return GNUTLS_E_NO_CERTIFICATE_FOUND; + + /* generate a list of gnutls_certs based on the auth info + * raw certs. + */ + peer_certificate_list_size = cert_list_length; + peer_certificate_list = + gnutls_calloc(1, + peer_certificate_list_size * + sizeof(gnutls_x509_crt)); + if (peer_certificate_list == NULL) { + gnutls_assert(); + ret = GNUTLS_E_MEMORY_ERROR; + goto cleanup; + } + + ca_certificate_list_size = CA_list_length; + ca_certificate_list = + gnutls_calloc(1, + ca_certificate_list_size * + sizeof(gnutls_x509_crt)); + if (ca_certificate_list == NULL) { + gnutls_assert(); + ret = GNUTLS_E_MEMORY_ERROR; + goto cleanup; + } + + /* allocate memory for CRL + */ + crl_list_size = CRL_list_length; + crl_list = + gnutls_calloc(1, + crl_list_size * + sizeof(gnutls_x509_crl)); + if (crl_list == NULL) { + gnutls_assert(); + ret = GNUTLS_E_MEMORY_ERROR; + goto cleanup; + } + + /* convert certA_list to gnutls_cert* list + */ + for (i = 0; i < peer_certificate_list_size; i++) { + ret = gnutls_x509_crt_init( &peer_certificate_list[i]); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + ret = + gnutls_x509_crt_import(peer_certificate_list[i], + &cert_list[i], GNUTLS_X509_FMT_DER); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + } + + /* convert CA_list to gnutls_x509_cert* list + */ + for (i = 0; i < ca_certificate_list_size; i++) { + ret = gnutls_x509_crt_init(&ca_certificate_list[i]); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + ret = + gnutls_x509_crt_import(ca_certificate_list[i], + &CA_list[i], GNUTLS_X509_FMT_DER); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + } + +#ifdef ENABLE_PKI + /* convert CRL_list to gnutls_x509_crl* list + */ + for (i = 0; i < crl_list_size; i++) { + ret = gnutls_x509_crl_init( &crl_list[i]); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + ret = + gnutls_x509_crl_import(crl_list[i], + &CRL_list[i], GNUTLS_X509_FMT_DER); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + } +#endif + + /* Verify certificate + */ + ret = + gnutls_x509_crt_list_verify(peer_certificate_list, + peer_certificate_list_size, + ca_certificate_list, ca_certificate_list_size, + crl_list, crl_list_size, 0, &verify); + + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + ret = verify; + + cleanup: + + if (peer_certificate_list != NULL) + for(x=0;x<peer_certificate_list_size;x++) { + if (peer_certificate_list[x] != NULL) + gnutls_x509_crt_deinit(peer_certificate_list[x]); + } + + if (ca_certificate_list != NULL) + for(x=0;x<ca_certificate_list_size;x++) { + if (ca_certificate_list[x] != NULL) + gnutls_x509_crt_deinit(ca_certificate_list[x]); + } + +#ifdef ENABLE_PKI + if (crl_list != NULL) + for(x=0;x<crl_list_size;x++) { + if (crl_list[x] != NULL) + gnutls_x509_crl_deinit(crl_list[x]); + } + + gnutls_free( crl_list); +#endif + + gnutls_free( ca_certificate_list); + gnutls_free( peer_certificate_list); + + return ret; +} + +/** + * gnutls_x509_extract_key_pk_algorithm - This function returns the keys's PublicKey algorithm + * @cert: is a DER encoded private key + * + * This function will return the public key algorithm of a DER encoded private + * key. + * + * Returns a member of the gnutls_pk_algorithm enumeration on success, + * or GNUTLS_E_UNKNOWN_PK_ALGORITHM on error. + * + **/ +int gnutls_x509_extract_key_pk_algorithm( const gnutls_datum * key) +{ + gnutls_x509_privkey pkey; + int ret, pk; + + ret = gnutls_x509_privkey_init( &pkey); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + ret = gnutls_x509_privkey_import( pkey, key, GNUTLS_X509_FMT_DER); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + pk = gnutls_x509_privkey_get_pk_algorithm( pkey); + + gnutls_x509_privkey_deinit( pkey); + return pk; +} + +#ifdef ENABLE_PKI + +/** + * gnutls_x509_pkcs7_extract_certificate - This function returns a certificate in a PKCS7 certificate set + * @pkcs7_struct: should contain a PKCS7 DER formatted structure + * @indx: contains the index of the certificate to extract + * @certificate: the contents of the certificate will be copied there + * @certificate_size: should hold the size of the certificate + * + * This function will return a certificate of the PKCS7 or RFC2630 certificate set. + * Returns 0 on success. If the provided buffer is not long enough, + * then GNUTLS_E_SHORT_MEMORY_BUFFER is returned. + * + * After the last certificate has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE + * will be returned. + * + **/ +int gnutls_x509_pkcs7_extract_certificate(const gnutls_datum * pkcs7_struct, int indx, char* certificate, int* certificate_size) +{ + gnutls_pkcs7 pkcs7; + int result; + size_t size = *certificate_size; + + result = gnutls_pkcs7_init( &pkcs7); + if (result < 0) return result; + + result = gnutls_pkcs7_import( pkcs7, pkcs7_struct, GNUTLS_X509_FMT_DER); + if (result < 0) { + gnutls_pkcs7_deinit( pkcs7); + return result; + } + + result = gnutls_pkcs7_get_crt_raw( pkcs7, indx, certificate, &size); + *certificate_size = size; + + gnutls_pkcs7_deinit( pkcs7); + + return result; +} + + +/** + * gnutls_x509_pkcs7_extract_certificate_count - This function returns the number of certificates in a PKCS7 certificate set + * @pkcs7_struct: should contain a PKCS7 DER formatted structure + * + * This function will return the number of certifcates in the PKCS7 or + * RFC2630 certificate set. + * + * Returns a negative value on failure. + * + **/ +int gnutls_x509_pkcs7_extract_certificate_count(const gnutls_datum * pkcs7_struct) +{ + gnutls_pkcs7 pkcs7; + int result; + + result = gnutls_pkcs7_init( &pkcs7); + if (result < 0) return result; + + result = gnutls_pkcs7_import( pkcs7, pkcs7_struct, GNUTLS_X509_FMT_DER); + if (result < 0) { + gnutls_pkcs7_deinit( pkcs7); + return result; + } + + result = gnutls_pkcs7_get_crt_count( pkcs7); + + gnutls_pkcs7_deinit( pkcs7); + + return result; +} + +#endif diff --git a/libextra/openssl_compat.h b/libextra/openssl_compat.h new file mode 100644 index 0000000000..aa9f931c54 --- /dev/null +++ b/libextra/openssl_compat.h @@ -0,0 +1,33 @@ +#ifndef GNUTLS_COMPAT8_H +# define GNUTLS_COMPAT8_H + +/* Extra definitions */ +#include <gnutls/openssl.h> + +int gnutls_x509_extract_dn( const gnutls_datum*, gnutls_x509_dn*); +int gnutls_x509_extract_dn_string(const gnutls_datum * idn, + char *buf, unsigned int sizeof_buf); +int gnutls_x509_extract_certificate_dn( const gnutls_datum*, gnutls_x509_dn*); +int gnutls_x509_extract_certificate_dn_string(char *buf, unsigned int sizeof_buf, + const gnutls_datum * cert, int issuer); +int gnutls_x509_extract_certificate_issuer_dn( const gnutls_datum*, gnutls_x509_dn *); +int gnutls_x509_extract_certificate_version( const gnutls_datum*); +int gnutls_x509_extract_certificate_serial(const gnutls_datum * cert, char* result, int* result_size); +time_t gnutls_x509_extract_certificate_activation_time( const gnutls_datum*); +time_t gnutls_x509_extract_certificate_expiration_time( const gnutls_datum*); +int gnutls_x509_extract_certificate_subject_alt_name( const gnutls_datum*, int seq, char*, int*); +int gnutls_x509_pkcs7_extract_certificate(const gnutls_datum * pkcs7_struct, int indx, char* certificate, int* certificate_size); +int gnutls_x509_extract_certificate_pk_algorithm( const gnutls_datum * cert, int* bits); +int gnutls_x509_extract_certificate_ca_status(const gnutls_datum * cert); +int gnutls_x509_extract_key_pk_algorithm( const gnutls_datum * key); + +int gnutls_x509_verify_certificate( const gnutls_datum* cert_list, int cert_list_length, const gnutls_datum * CA_list, int CA_list_length, const gnutls_datum* CRL_list, int CRL_list_length); + +#define gnutls_x509_fingerprint gnutls_fingerprint +#define gnutls_x509_certificate_format gnutls_x509_crt_fmt + +int gnutls_x509_extract_key_pk_algorithm( const gnutls_datum * key); + +#define gnutls_certificate_set_rsa_params gnutls_certificate_set_rsa_export_params + +#endif |