diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2002-02-01 11:14:47 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2002-02-01 11:14:47 +0000 |
commit | 4eb7eee2eebdf38466a955b73e122933422491bf (patch) | |
tree | 9719b14062087936fd518b56b7afbe64d382f969 | |
parent | 0a048d3c44bb23f6856587779c5ae0435d54f388 (diff) | |
download | gnutls-4eb7eee2eebdf38466a955b73e122933422491bf.tar.gz |
Several changes in certificate and key handling.
* gnutls_certificate_allocate_sc() does not require the ncerts argument
-rw-r--r-- | configure.in | 4 | ||||
-rw-r--r-- | doc/protocol/draft-ietf-tls-openpgp-keys-01.txt | 3 | ||||
-rw-r--r-- | doc/tex/ex1.tex | 4 | ||||
-rw-r--r-- | doc/tex/ex2.tex | 4 | ||||
-rw-r--r-- | doc/tex/ex3.tex | 2 | ||||
-rw-r--r-- | doc/tex/serv1.tex | 6 | ||||
-rw-r--r-- | lib/Makefile.am | 2 | ||||
-rw-r--r-- | lib/auth_cert.c | 6 | ||||
-rw-r--r-- | lib/auth_cert.h | 3 | ||||
-rw-r--r-- | lib/gnutls.h.in.in | 18 | ||||
-rw-r--r-- | lib/gnutls_cert.c | 1212 | ||||
-rw-r--r-- | lib/gnutls_cert.h | 9 | ||||
-rw-r--r-- | lib/gnutls_int_compat.c | 47 | ||||
-rw-r--r-- | lib/gnutls_session_pack.c | 20 | ||||
-rw-r--r-- | lib/gnutls_ui.h | 2 | ||||
-rw-r--r-- | lib/gnutls_x509.c | 1187 | ||||
-rw-r--r-- | lib/x509_extensions.c | 2 | ||||
-rw-r--r-- | src/cli.c | 10 | ||||
-rw-r--r-- | src/common.h | 2 | ||||
-rw-r--r-- | src/serv.c | 8 |
20 files changed, 1275 insertions, 1276 deletions
diff --git a/configure.in b/configure.in index 950c145a8f..07ae174d71 100644 --- a/configure.in +++ b/configure.in @@ -11,8 +11,8 @@ AC_DEFINE_UNQUOTED(T_OS, "$target_os") dnl Gnutls Version GNUTLS_MAJOR_VERSION=0 -GNUTLS_MINOR_VERSION=3 -GNUTLS_MICRO_VERSION=90 +GNUTLS_MINOR_VERSION=4 +GNUTLS_MICRO_VERSION=0 GNUTLS_VERSION=$GNUTLS_MAJOR_VERSION.$GNUTLS_MINOR_VERSION.$GNUTLS_MICRO_VERSION AC_DEFINE_UNQUOTED(GNUTLS_VERSION, "$GNUTLS_VERSION") diff --git a/doc/protocol/draft-ietf-tls-openpgp-keys-01.txt b/doc/protocol/draft-ietf-tls-openpgp-keys-01.txt index a52b1679a9..c17061d631 100644 --- a/doc/protocol/draft-ietf-tls-openpgp-keys-01.txt +++ b/doc/protocol/draft-ietf-tls-openpgp-keys-01.txt @@ -64,7 +64,8 @@ Internet-Draft Using OpenPGP keys for TLS Authentication January 2002 At the time of writing, TLS [TLS] uses the X.509 protocols, to provide certificate services. However these protocols, are limited to hierarchical key management. This leads to a problem when - de-centralized application protocols are to be supported. + applications, which do not have the concept of a central authority, + are to be supported. OpenPGP keys (sometimes called OpenPGP certificates), provide security services for electronic communications. They are widely diff --git a/doc/tex/ex1.tex b/doc/tex/ex1.tex index ffe7540250..6f1ab1d8a8 100644 --- a/doc/tex/ex1.tex +++ b/doc/tex/ex1.tex @@ -46,11 +46,11 @@ int main() exit(1); } /* X509 stuff */ - if (gnutls_certificate_allocate_client_sc(&xcred, 0) < 0) { /* no client private key */ + if (gnutls_certificate_allocate_client_sc(&xcred) < 0) { fprintf(stderr, "memory error\n"); exit(1); } - gnutls_x509pki_set_client_trust_file(xcred, CAFILE, CRLFILE); + gnutls_certificate_set_x509_trust_file(xcred, CAFILE, CRLFILE); for (t = 0; t < 2; t++) { /* connect 2 times to the server */ diff --git a/doc/tex/ex2.tex b/doc/tex/ex2.tex index ca9d9158af..bb79f43821 100644 --- a/doc/tex/ex2.tex +++ b/doc/tex/ex2.tex @@ -36,13 +36,13 @@ int main() exit(1); } /* X509 stuff */ - if (gnutls_certificate_allocate_client_sc(&xcred, 0) < 0) { /* no client private key */ + if (gnutls_certificate_allocate_client_sc(&xcred) < 0) { fprintf(stderr, "memory error\n"); exit(1); } /* set's the trusted cas file */ - gnutls_x509pki_set_client_trust_file(xcred, CAFILE, CRLFILE); + gnutls_certificate_set_x509_trust_file(xcred, CAFILE, CRLFILE); /* connects to server */ diff --git a/doc/tex/ex3.tex b/doc/tex/ex3.tex index 81c72a52da..86693ff784 100644 --- a/doc/tex/ex3.tex +++ b/doc/tex/ex3.tex @@ -39,7 +39,7 @@ int print_info(GNUTLS_STATE state) /* in case of X509 PKI */ cert_list = gnutls_certificate_get_peers(state, &cert_list_size); - status = gnutls_x509pki_client_get_peer_certificate_status(state); + status = gnutls_certificate_verify_peers(state); switch (status) { case GNUTLS_CERT_NOT_TRUSTED: diff --git a/doc/tex/serv1.tex b/doc/tex/serv1.tex index 6d2315be7c..e2ac90fc30 100644 --- a/doc/tex/serv1.tex +++ b/doc/tex/serv1.tex @@ -129,15 +129,15 @@ int main() fprintf(stderr, "global state initialization error\n"); exit(1); } - if (gnutls_certificate_allocate_server_sc(&x509_cred, 1) < 0) { + if (gnutls_certificate_allocate_server_sc(&x509_cred) < 0) { fprintf(stderr, "memory error\n"); exit(1); } - if (gnutls_x509pki_set_server_trust_file(x509_cred, CAFILE, CRLFILE) < 0) { + if (gnutls_certificate_set_x509_trust_file(x509_cred, CAFILE, CRLFILE) < 0) { fprintf(stderr, "X509 PARSE ERROR\nDid you have ca.pem?\n"); exit(1); } - if (gnutls_x509pki_set_server_key_file(x509_cred, CERTFILE, KEYFILE) < 0) { + if (gnutls_certifcate_set_x509_key_file(x509_cred, CERTFILE, KEYFILE) < 0) { fprintf(stderr, "X509 PARSE ERROR\nDid you have key.pem and cert.pem?\n"); exit(1); } diff --git a/lib/Makefile.am b/lib/Makefile.am index 28189c8c7b..12d3ddde02 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -18,7 +18,7 @@ EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls.asn pkix.asn \ gnutls_privkey.h gnutls_constate.h gnutls_global.h x509_verify.h \ gnutls_sig.h gnutls_mem.h x509_extensions.h gnutls_ui.h \ gnutls-api.tex io_debug.h ext_max_record.h gnutls_session_pack.h \ - gnutls_alert.h asn1-api.tex gnutls_str.h gnutls_state.h + gnutls_alert.h asn1-api.tex gnutls_str.h gnutls_state.h gnutls_x509.h lib_LTLIBRARIES = libgnutls.la diff --git a/lib/auth_cert.c b/lib/auth_cert.c index aa537941c8..595579804c 100644 --- a/lib/auth_cert.c +++ b/lib/auth_cert.c @@ -38,11 +38,13 @@ #include <x509_extensions.h> #include <gnutls_state.h> #include <gnutls_pk.h> +#include <gnutls_x509.h> /* Copies data from a internal certificate struct (gnutls_cert) to * exported certificate struct (CERTIFICATE_AUTH_INFO) */ -int _gnutls_copy_x509_auth_info(CERTIFICATE_AUTH_INFO info, gnutls_cert * cert, +static +int _gnutls_copy_certificate_auth_info(CERTIFICATE_AUTH_INFO info, gnutls_cert * cert, int ncerts) { /* Copy peer's information to AUTH_INFO @@ -595,7 +597,7 @@ int _gnutls_proc_x509_server_certificate(GNUTLS_STATE state, opaque * data, peer_certificate_list[0].subject_pk_algorithm; if ((ret = - _gnutls_copy_x509_auth_info(info, peer_certificate_list, + _gnutls_copy_certificate_auth_info(info, peer_certificate_list, peer_certificate_list_size)) < 0) { gnutls_assert(); diff --git a/lib/auth_cert.h b/lib/auth_cert.h index 9a9a25c34d..7c17ebc7b6 100644 --- a/lib/auth_cert.h +++ b/lib/auth_cert.h @@ -19,6 +19,7 @@ typedef struct { * row (should be 1 for OpenPGP keys). */ int ncerts; /* contains the number of columns in cert_list. + * This is the same with the number of pkeys. */ gnutls_private_key * pkey; @@ -57,8 +58,6 @@ typedef struct CERTIFICATE_AUTH_INFO_INT { typedef struct CERTIFICATE_AUTH_INFO_INT CERTIFICATE_AUTH_INFO_INT; -int _gnutls_copy_x509_client_auth_info( CERTIFICATE_AUTH_INFO info, gnutls_cert* cert, CertificateStatus verify); - /* AUTH X509 functions */ int _gnutls_gen_x509_server_certificate(GNUTLS_STATE, opaque **); int _gnutls_gen_x509_client_certificate(GNUTLS_STATE, opaque **); diff --git a/lib/gnutls.h.in.in b/lib/gnutls.h.in.in index cfd169f6c2..1e3721452f 100644 --- a/lib/gnutls.h.in.in +++ b/lib/gnutls.h.in.in @@ -201,23 +201,23 @@ int gnutls_anon_set_client_cred( GNUTLS_ANON_SERVER_CREDENTIALS res, int dh_bits * KEYFILE is a pkcs-1 private key in PEM form (for RSA keys). */ void gnutls_certificate_free_sc( GNUTLS_CERTIFICATE_CREDENTIALS sc); -int gnutls_certificate_allocate_sc( GNUTLS_CERTIFICATE_CREDENTIALS *sc, int ncerts); +int gnutls_certificate_allocate_sc( GNUTLS_CERTIFICATE_CREDENTIALS *sc); -int gnutls_x509pki_set_trust_file( GNUTLS_CERTIFICATE_CREDENTIALS res, char* CAFILE, char* CRLFILE); -int gnutls_x509pki_set_trust_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const gnutls_datum *CA, const gnutls_datum *CRL); +int gnutls_certificate_set_x509_trust_file( GNUTLS_CERTIFICATE_CREDENTIALS res, char* CAFILE, char* CRLFILE); +int gnutls_certificate_set_x509_trust_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const gnutls_datum *CA, const gnutls_datum *CRL); -int gnutls_x509pki_set_key_file( GNUTLS_CERTIFICATE_CREDENTIALS res, char *CERTFILE, char* KEYFILE); -int gnutls_x509pki_set_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const gnutls_datum* CERT, const gnutls_datum* KEY); +int gnutls_certificate_set_x509_key_file( GNUTLS_CERTIFICATE_CREDENTIALS res, char *CERTFILE, char* KEYFILE); +int gnutls_certificate_set_x509_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const gnutls_datum* CERT, const gnutls_datum* KEY); #define gnutls_certificate_free_server_sc gnutls_certificate_free_sc #define gnutls_certificate_allocate_server_sc gnutls_certificate_allocate_sc -#define gnutls_certificate_set_server_key_file gnutls_certificate_set_key_file -#define gnutls_certificate_set_server_trust_file gnutls_certificate_set_trust_file +#define gnutls_certificate_set_server_x509_key_file gnutls_certificate_set_x509_key_file +#define gnutls_certificate_set_server_x509_trust_file gnutls_certificate_set_x509_trust_file #define gnutls_certificate_free_client_sc gnutls_certificate_free_sc #define gnutls_certificate_allocate_client_sc gnutls_certificate_allocate_sc -#define gnutls_certificate_set_client_key_file gnutls_certificate_set_key_file -#define gnutls_certificate_set_client_trust_file gnutls_certificate_set_trust_file +#define gnutls_certificate_set_client_x509_key_file gnutls_certificate_set_x509_key_file +#define gnutls_certificate_set_client_x509_trust_file gnutls_certificate_set_x509_trust_file /* global state functions diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index 4475f102bb..717b9d1a72 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -20,20 +20,22 @@ #include <gnutls_int.h> #include <gnutls_errors.h> -#include <x509_b64.h> #include <auth_cert.h> #include <gnutls_cert.h> #include <x509_asn1.h> #include <x509_der.h> #include <gnutls_datum.h> #include <gnutls_gcry.h> -#include <gnutls_privkey.h> #include <gnutls_global.h> #include <x509_verify.h> +#include <gnutls_privkey.h> #include <x509_extensions.h> #include <gnutls_algorithms.h> #include <gnutls_dh.h> #include <gnutls_str.h> +#include <gnutls_state.h> +#include <gnutls_auth_int.h> +#include <gnutls_x509.h> /* KX mappings to PK algorithms */ typedef struct { @@ -135,1184 +137,25 @@ void gnutls_certificate_free_sc(GNUTLS_CERTIFICATE_CREDENTIALS sc) gnutls_free(sc); } -#define MAX_FILE_SIZE 100*1024 -#define CERT_SEP "-----BEGIN" - -/* Reads a base64 encoded certificate from memory - */ -static int read_cert_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *cert, int cert_size) -{ - int siz, i, siz2; - opaque *b64; - const char *ptr; - gnutls_datum tmp; - int ret; - - ptr = cert; - siz = cert_size; - i = 1; - - res->cert_list[res->ncerts] = NULL; - - do { - siz2 = _gnutls_fbase64_decode(ptr, siz, &b64); - siz -= siz2; /* FIXME: this is not enough - */ - - if (siz2 < 0) { - gnutls_assert(); - gnutls_free(b64); - return GNUTLS_E_PARSING_ERROR; - } - - - res->cert_list[res->ncerts] = - (gnutls_cert *) gnutls_realloc(res-> - cert_list[res->ncerts], - i * - sizeof(gnutls_cert)); - - if (res->cert_list[res->ncerts] == NULL) { - gnutls_assert(); - gnutls_free(b64); - return GNUTLS_E_MEMORY_ERROR; - } - /* set defaults to zero - */ - memset(&res->cert_list[res->ncerts][i - 1], 0, - sizeof(gnutls_cert)); - - tmp.data = b64; - tmp.size = siz2; - - if ((ret = - _gnutls_x509_cert2gnutls_cert(&res-> - cert_list[res->ncerts][i - 1], - tmp)) < 0) { - gnutls_free(b64); - gnutls_assert(); - return ret; - } - gnutls_free(b64); - - /* now we move ptr after the pem header */ - ptr = strstr(ptr, CERT_SEP); - if (ptr!=NULL) - ptr++; - - i++; - } while ((ptr = strstr(ptr, CERT_SEP)) != NULL); - - res->cert_list_length[res->ncerts] = i - 1; - - /* WE DO NOT CATCH OVERRUNS in gnutls_x509pki_set_key(). - * This function should be called as many times as specified - * in certificate_allocate_sc(). - */ - res->ncerts++; - - return 0; -} - -/* Reads a base64 encoded CA list from memory - * This is to be called once. - */ -static int read_ca_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *ca, int ca_size) -{ - int siz, siz2, i; - opaque *b64; - const char *ptr; - int ret; - gnutls_datum tmp; - - siz = ca_size; - - ptr = ca; - - i = res->x509_ncas + 1; - - do { - siz2 = _gnutls_fbase64_decode(ptr, siz, &b64); - siz -= siz2; /* FIXME: this is not enough - */ - - if (siz2 < 0) { - gnutls_assert(); - gnutls_free(b64); - return GNUTLS_E_PARSING_ERROR; - } - - res->x509_ca_list = - (gnutls_cert *) gnutls_realloc(res->x509_ca_list, - i * - sizeof(gnutls_cert)); - if (res->x509_ca_list == NULL) { - gnutls_assert(); - gnutls_free(b64); - return GNUTLS_E_MEMORY_ERROR; - } - memset(&res->x509_ca_list[i - 1], 0, sizeof(gnutls_cert)); - - tmp.data = b64; - tmp.size = siz2; - - if ((ret = - _gnutls_x509_cert2gnutls_cert(&res->x509_ca_list[i - 1], - tmp)) < 0) { - gnutls_assert(); - gnutls_free(b64); - return ret; - } - gnutls_free(b64); - - /* now we move ptr after the pem header */ - ptr = strstr(ptr, CERT_SEP); - if (ptr!=NULL) - ptr++; - - i++; - } while ((ptr = strstr(ptr, CERT_SEP)) != NULL); - - res->x509_ncas = i - 1; - - - - return 0; -} - - -/* Reads a PEM encoded PKCS-1 RSA private key from memory - * 2002-01-26: Added ability to read DSA keys. - */ -static int read_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *key, int key_size) -{ - int siz, ret; - opaque *b64; - gnutls_datum tmp; - PKAlgorithm pk; - - /* read PKCS-1 private key */ - siz = key_size; - - - /* If we find the "DSA PRIVATE" string in the - * pem encoded certificate then it's a DSA key. - */ - if (strstr( key, "DSA PRIVATE")!=NULL) - pk = GNUTLS_PK_DSA; - else - pk = GNUTLS_PK_RSA; - - siz = _gnutls_fbase64_decode(key, siz, &b64); - - if (siz < 0) { - gnutls_assert(); - gnutls_free(b64); - return GNUTLS_E_PARSING_ERROR; - } - - tmp.data = b64; - tmp.size = siz; - - switch (pk) { /* decode the key */ - case GNUTLS_PK_RSA: - if ((ret = - _gnutls_PKCS1key2gnutlsKey(&res->pkey[res->ncerts], - tmp)) < 0) { - gnutls_assert(); - gnutls_free(b64); - return ret; - } - break; - case GNUTLS_PK_DSA: - if ((ret = - _gnutls_DSAkey2gnutlsKey(&res->pkey[res->ncerts], - tmp)) < 0) { - gnutls_assert(); - gnutls_free(b64); - return ret; - } - break; - } - gnutls_free(b64); - - return 0; -} - -/* Reads a base64 encoded certificate file - */ -static int read_cert_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *certfile) -{ - int siz; - char x[MAX_FILE_SIZE]; - FILE *fd1; - - fd1 = fopen(certfile, "r"); - if (fd1 == NULL) - return GNUTLS_E_UNKNOWN_ERROR; - - siz = fread(x, 1, sizeof(x), fd1); - fclose(fd1); - - x[siz-1] = 0; - - return read_cert_mem( res, x, siz); - -} - -/* Reads a base64 encoded CA file (file contains multiple certificate - * authorities). This is to be called once. - */ -static int read_ca_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *cafile) -{ - int siz; - char x[MAX_FILE_SIZE]; - FILE *fd1; - - fd1 = fopen(cafile, "r"); - if (fd1 == NULL) { - gnutls_assert(); - return GNUTLS_E_UNKNOWN_ERROR; - } - - siz = fread(x, 1, sizeof(x), fd1); - fclose(fd1); - - x[siz-1] = 0; - - return read_ca_mem( res, x, siz); -} - - -/* Reads a PEM encoded PKCS-1 RSA private key file - */ -static int read_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *keyfile) -{ - int siz; - char x[MAX_FILE_SIZE]; - FILE *fd2; - - fd2 = fopen(keyfile, "r"); - if (fd2 == NULL) - return GNUTLS_E_UNKNOWN_ERROR; - - siz = fread(x, 1, sizeof(x), fd2); - fclose(fd2); - - x[siz-1] = 0; - - return read_key_mem( res, x, siz); -} /** * gnutls_certificate_allocate_sc - Used to allocate an x509 SERVER CREDENTIALS structure * @res: is a pointer to an &GNUTLS_CERTIFICATE_CREDENTIALS structure. - * @ncerts: this is the number of certificate/private key pair you're going to use. - * This should be 1 in common sites. * * This structure is complex enough to manipulate directly thus * this helper function is provided in order to allocate * the structure. **/ -int gnutls_certificate_allocate_sc(GNUTLS_CERTIFICATE_CREDENTIALS * res, int ncerts) +int gnutls_certificate_allocate_sc(GNUTLS_CERTIFICATE_CREDENTIALS * res) { -#warning FIX NCERTS *res = gnutls_calloc(1, sizeof(CERTIFICATE_CREDENTIALS_INT)); if (*res == NULL) return GNUTLS_E_MEMORY_ERROR; - - (*res)->ncerts = 0; /* this is right - set_key() increments it */ - - if (ncerts > 0) { - (*res)->cert_list = - (gnutls_cert **) gnutls_malloc(ncerts * - sizeof(gnutls_cert *)); - - if ((*res)->cert_list == NULL) { - gnutls_free(*res); - return GNUTLS_E_MEMORY_ERROR; - } - - (*res)->cert_list_length = - (int *) gnutls_malloc(ncerts * sizeof(int *)); - if ((*res)->cert_list_length == NULL) { - gnutls_free(*res); - gnutls_free((*res)->cert_list); - return GNUTLS_E_MEMORY_ERROR; - } - - (*res)->pkey = - gnutls_malloc(ncerts * sizeof(gnutls_private_key)); - if ((*res)->pkey == NULL) { - gnutls_free(*res); - gnutls_free((*res)->cert_list); - gnutls_free((*res)->cert_list_length); - return GNUTLS_E_MEMORY_ERROR; - } - - } - return 0; } -/* returns error if the certificate has different algorithm than - * the given key parameters. - */ -static int _gnutls_check_key_cert_match( GNUTLS_CERTIFICATE_CREDENTIALS res) { - if (res->pkey->pk_algorithm != res->cert_list[0]->subject_pk_algorithm) { - gnutls_assert(); - return GNUTLS_E_CERTIFICATE_KEY_MISMATCH; - } - return 0; -} - - -/** - * gnutls_x509pki_set_key_file - Used to set keys in a GNUTLS_CERTIFICATE_CREDENTIALS structure - * @res: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure. - * @CERTFILE: is a PEM encoded file containing the certificate list (path) for - * the specified private key - * @KEYFILE: is a PEM encoded file containing a private key - * - * This function sets a certificate/private key pair in the - * GNUTLS_CERTIFICATE_CREDENTIALS structure. This function may be called - * more than once (in case multiple keys/certificates exist for the - * server). - * - * Currently only PKCS-1 PEM encoded RSA and DSA private keys are accepted by - * this function. - * - **/ -int gnutls_x509pki_set_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *CERTFILE, - char *KEYFILE) -{ - int ret; - - /* this should be first - */ - if ((ret = read_key_file(res, KEYFILE)) < 0) - return ret; - - if ((ret = read_cert_file(res, CERTFILE)) < 0) - return ret; - - if ((ret=_gnutls_check_key_cert_match( res)) < 0) { - gnutls_assert(); - return ret; - } - - return 0; -} - -static int generate_rdn_seq( GNUTLS_CERTIFICATE_CREDENTIALS res) { -gnutls_datum tmp; -int ret, size, i; -opaque *pdata; - - /* Generate the RDN sequence - * This will be sent to clients when a certificate - * request message is sent. - */ - - /* FIXME: in case of a client it is not needed - * to do that. This would save time and memory. - * However we don't have that information available - * here. - */ - - size = 0; - for (i = 0; i < res->x509_ncas; i++) { - if ((ret = _gnutls_find_dn(&tmp, &res->x509_ca_list[i])) < 0) { - gnutls_assert(); - return ret; - } - size += (2 + tmp.size); - } - - if (res->x509_rdn_sequence.data != NULL) - gnutls_free( res->x509_rdn_sequence.data); - - res->x509_rdn_sequence.data = gnutls_malloc(size); - if (res->x509_rdn_sequence.data == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - res->x509_rdn_sequence.size = size; - - pdata = res->x509_rdn_sequence.data; - - for (i = 0; i < res->x509_ncas; i++) { - if ((ret = _gnutls_find_dn(&tmp, &res->x509_ca_list[i])) < 0) { - gnutls_free(res->x509_rdn_sequence.data); - res->x509_rdn_sequence.size = 0; - res->x509_rdn_sequence.data = NULL; - gnutls_assert(); - return ret; - } - WRITEdatum16(pdata, tmp); - pdata += (2 + tmp.size); - } - - return 0; -} - -/** - * gnutls_x509pki_set_trust_mem - Used to add trusted CAs in a GNUTLS_CERTIFICATE_CREDENTIALS structure - * @res: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure. - * @CA: is a PEM encoded list of trusted CAs - * @CRL: is a PEM encoded list of CRLs (ignored for now) - * - * This function adds the trusted CAs in order to verify client - * certificates. This function may be called multiple times. - * - **/ -int gnutls_x509pki_set_trust_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const gnutls_datum *CA, - const gnutls_datum *CRL) -{ - int ret; - - if ((ret = read_ca_mem(res, CA->data, CA->size)) < 0) - return ret; - - if ((ret = generate_rdn_seq(res)) < 0) - return ret; - - return 0; -} - -/** - * gnutls_x509pki_set_trust_file - Used to add trusted CAs in a GNUTLS_CERTIFICATE_CREDENTIALS structure - * @res: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure. - * @CAFILE: is a PEM encoded file containing trusted CAs - * @CRLFILE: is a PEM encoded file containing CRLs (ignored for now) - * - * This function sets the trusted CAs in order to verify client - * certificates. This function may be called multiple times. - * - **/ -int gnutls_x509pki_set_trust_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *CAFILE, - char *CRLFILE) -{ - int ret; - - if ((ret = read_ca_file(res, CAFILE)) < 0) - return ret; - - if ((ret = generate_rdn_seq(res)) < 0) - return ret; - - return 0; -} - - -/** - * gnutls_x509pki_set_key_mem - Used to set keys in a GNUTLS_CERTIFICATE_CREDENTIALS structure - * @res: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure. - * @CERT: contains a PEM encoded certificate list (path) for - * the specified private key - * @KEY: is a PEM encoded private key - * - * This function sets a certificate/private key pair in the - * GNUTLS_CERTIFICATE_CREDENTIALS structure. This function may be called - * more than once (in case multiple keys/certificates exist for the - * server). - * - * Currently only PKCS-1 PEM encoded RSA private keys are accepted by - * this function. - * - **/ -int gnutls_x509pki_set_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const gnutls_datum* CERT, - const gnutls_datum* KEY) -{ - int ret; - - /* this should be first - */ - if ((ret = read_key_mem( res, KEY->data, KEY->size)) < 0) - return ret; - - if ((ret = read_cert_mem( res, CERT->data, CERT->size)) < 0) - return ret; - - if ((ret=_gnutls_check_key_cert_match( res)) < 0) { - gnutls_assert(); - return ret; - } - - return 0; -} - - -static int _read_rsa_params(opaque * der, int dersize, MPI * params) -{ - opaque str[MAX_PARAMETER_SIZE]; - int result; - node_asn *spk; - - if (asn1_create_structure - (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPublicKey", &spk, - "rsa_public_key") != ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_ERROR; - } - - result = asn1_get_der(spk, der, dersize); - - if (result != ASN_OK) { - gnutls_assert(); - asn1_delete_structure(spk); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - - if ( (result=_gnutls_x509_read_int( spk, "rsa_public_key.modulus", - str, sizeof(str)-1, ¶ms[0])) < 0) { - gnutls_assert(); - asn1_delete_structure(spk); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - if ( (result=_gnutls_x509_read_int( spk, "rsa_public_key.publicExponent", - str, sizeof(str)-1, ¶ms[1])) < 0) { - gnutls_assert(); - _gnutls_mpi_release(¶ms[0]); - asn1_delete_structure(spk); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - asn1_delete_structure(spk); - - return 0; - -} - - -/* reads p,q and g - * from the certificate - * params[0-2] - */ -static int _read_dsa_params(opaque * der, int dersize, MPI * params) -{ - opaque str[MAX_PARAMETER_SIZE]; - int result; - node_asn *spk; - - if (asn1_create_structure - (_gnutls_get_pkix(), "PKIX1Implicit88.Dss-Parms", &spk, - "dsa_parms") != ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_ERROR; - } - - result = asn1_get_der(spk, der, dersize); - - if (result != ASN_OK) { - gnutls_assert(); - asn1_delete_structure(spk); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - /* FIXME: If the parameters are not included in the certificate - * then the issuer's parameters should be used. - */ - - /* Read p */ - - if ( (result=_gnutls_x509_read_int( spk, "dsa_parms.p", str, sizeof(str)-1, ¶ms[0])) < 0) { - gnutls_assert(); - asn1_delete_structure(spk); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - /* Read q */ - - if ( (result=_gnutls_x509_read_int( spk, "dsa_parms.q", str, sizeof(str)-1, ¶ms[1])) < 0) { - gnutls_assert(); - asn1_delete_structure(spk); - _gnutls_mpi_release(¶ms[0]); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - /* Read g */ - - if ( (result=_gnutls_x509_read_int( spk, "dsa_parms.g", str, sizeof(str)-1, ¶ms[2])) < 0) { - gnutls_assert(); - asn1_delete_structure(spk); - _gnutls_mpi_release(¶ms[0]); - _gnutls_mpi_release(¶ms[1]); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - asn1_delete_structure(spk); - - return 0; - -} - -/* reads DSA's Y - * from the certificate - * params[3] - */ -static int _read_dsa_pubkey(opaque * der, int dersize, MPI * params) -{ - opaque str[MAX_PARAMETER_SIZE]; - int result; - node_asn *spk; - - if ( (result=asn1_create_structure - (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey", &spk, - "dsa_public_key")) != ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_ERROR; - } - - result = asn1_get_der(spk, der, dersize); - - if (result != ASN_OK) { - gnutls_assert(); - asn1_delete_structure(spk); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - /* Read p */ - - if ( (result=_gnutls_x509_read_int( spk, "dsa_public_key", str, sizeof(str)-1, ¶ms[3])) < 0) { - gnutls_assert(); - asn1_delete_structure(spk); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - asn1_delete_structure(spk); - - return 0; - -} - - -#define _READ(a, aa, b, c, d, e, res, f) \ - result = _IREAD(a, aa, sizeof(aa), b, c, d, e, res, sizeof(res)-1, f); \ - if (result<0) return result; \ - if (result==1) continue - - -int _IREAD(node_asn * rasn, char *name3, int name3_size, char *rstr, char *OID, - char *ANAME, char *TYPE, char *res, int res_size, int CHOICE) -{ - char name2[256]; - int result, len; - char str[1024]; - node_asn *tmpasn; - - if (strcmp(rstr, OID) == 0) { - - _gnutls_str_cpy(str, sizeof(str), "PKIX1Implicit88."); - _gnutls_str_cat(str, sizeof(str), ANAME); - _gnutls_str_cpy(name2, sizeof(name2), "temp-structure-"); - _gnutls_str_cat(name2, sizeof(name2), TYPE); - - if ((result = - asn1_create_structure(_gnutls_get_pkix(), str, - &tmpasn, name2)) != ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_ERROR; - } - - len = sizeof(str) -1; - if ((result = - asn1_read_value(rasn, name3, str, &len)) != ASN_OK) { - asn1_delete_structure(tmpasn); - return 1; - } - - if ((result = asn1_get_der(tmpasn, str, len)) != ASN_OK) { - asn1_delete_structure(tmpasn); - return 1; - } - _gnutls_str_cpy(name3, name3_size, name2); - - len = sizeof(str) - 1; - if ((result = asn1_read_value(tmpasn, name3, str, &len)) != ASN_OK) { /* CHOICE */ - asn1_delete_structure(tmpasn); - return 1; - } - - if (CHOICE == 0) { - str[len] = 0; - /* strlen(str) < res_size, checked above */ - _gnutls_str_cpy(res, res_size, str); - - } else { /* CHOICE */ - str[len] = 0; - _gnutls_str_cat(name3, name3_size, "."); - _gnutls_str_cat(name3, name3_size, str); - len = sizeof(str) - 1; - - if ((result = - asn1_read_value(tmpasn, name3, str, - &len)) != ASN_OK) { - asn1_delete_structure(tmpasn); - return 1; - } - str[len] = 0; - if ( len < res_size) - _gnutls_str_cpy(res, res_size, str); - } - asn1_delete_structure(tmpasn); - - } - return 0; -} - -/* this function will convert up to 3 digit - * numbers to characters. - */ -void _gnutls_int2str(int k, char *data) -{ - if (k > 999) - data[0] = 0; - else - sprintf(data, "%d", k); -} - -/* This function will attempt to read a Name - * ASN.1 structure. (Taken from Fabio's samples!) - * - * FIXME: These functions need carefull auditing - * (they're complex enough) - * --nmav - */ -int _gnutls_get_name_type(node_asn * rasn, char *root, gnutls_DN * dn) -{ - int k, k2, result, len; - char name[128], str[1024], name2[128], counter[MAX_INT_DIGITS], - name3[128]; - - k = 0; - do { - k++; - - _gnutls_str_cpy(name, sizeof(name), root); - _gnutls_str_cat(name, sizeof(name), ".rdnSequence.?"); - _gnutls_int2str(k, counter); - _gnutls_str_cat(name, sizeof(name), counter); - - len = sizeof(str) - 1; - - result = asn1_read_value(rasn, name, str, &len); - - /* move to next - */ - if (result == ASN_ELEMENT_NOT_FOUND) - break; - if (result != ASN_VALUE_NOT_FOUND) { - gnutls_assert(); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - k2 = 0; - do { - k2++; - - _gnutls_str_cpy(name2, sizeof(name2), name); - _gnutls_str_cat(name2, sizeof(name2), ".?"); - _gnutls_int2str(k2, counter); - _gnutls_str_cat(name2, sizeof(name2), counter); - - len = sizeof(str) - 1; - result = asn1_read_value(rasn, name2, str, &len); - - if (result == ASN_ELEMENT_NOT_FOUND) - break; - if (result != ASN_VALUE_NOT_FOUND) { - gnutls_assert(); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - _gnutls_str_cpy(name3, sizeof(name3), name2); - _gnutls_str_cat(name3, sizeof(name3), ".type"); - - len = sizeof(str) - 1; - result = asn1_read_value(rasn, name3, str, &len); - - if (result == ASN_ELEMENT_NOT_FOUND) - break; - else if (result != ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - _gnutls_str_cpy(name3, sizeof(name3), name2); - _gnutls_str_cat(name3, sizeof(name3), ".value"); - - if (result == ASN_OK) { -#ifdef DEBUG -# warning " FIX COUNTRY HERE" -#endif - _READ(rasn, name3, str, "2 5 4 6", - "X520OrganizationName", - "countryName", dn->country, 1); - _READ(rasn, name3, str, "2 5 4 10", - "X520OrganizationName", - "OrganizationName", dn->organization, - 1); - _READ(rasn, name3, str, "2 5 4 11", - "X520OrganizationalUnitName", - "OrganizationalUnitName", - dn->organizational_unit_name, 1); - _READ(rasn, name3, str, "2 5 4 3", - "X520CommonName", "CommonName", - dn->common_name, 1); - _READ(rasn, name3, str, "2 5 4 7", - "X520LocalityName", "LocalityName", - dn->locality_name, 1); - _READ(rasn, name3, str, "2 5 4 8", - "X520StateOrProvinceName", - "StateOrProvinceName", - dn->state_or_province_name, 1); - _READ(rasn, name3, str, - "1 2 840 113549 1 9 1", "Pkcs9email", - "emailAddress", dn->email, 0); - } - } while (1); - } while (1); - - if (result == ASN_ELEMENT_NOT_FOUND) - return 0; - else - return GNUTLS_E_ASN1_PARSING_ERROR; -} - - - -#define MAX_TIME 1024 -time_t _gnutls_get_time(node_asn * c2, char *root, char *when) -{ - opaque ttime[MAX_TIME]; - char name[1024]; - time_t ctime; - int len, result; - - _gnutls_str_cpy(name, sizeof(name), root); - _gnutls_str_cat(name, sizeof(name), ".tbsCertificate.validity."); - _gnutls_str_cat(name, sizeof(name), when); - - len = sizeof(ttime) - 1; - if ((result = asn1_read_value(c2, name, ttime, &len)) < 0) { - gnutls_assert(); - return (time_t) (-1); - } - - /* CHOICE */ - _gnutls_str_cpy(name, sizeof(name), root); - - if (strcmp(ttime, "GeneralizedTime") == 0) { - - _gnutls_str_cat(name, sizeof(name), ".tbsCertificate.validity."); - _gnutls_str_cat(name, sizeof(name), when); - _gnutls_str_cat(name, sizeof(name), ".generalTime"); - len = sizeof(ttime) - 1; - result = asn1_read_value(c2, name, ttime, &len); - if (result == ASN_OK) - ctime = _gnutls_generalTime2gtime(ttime); - } else { /* UTCTIME */ - - _gnutls_str_cat(name, sizeof(name), ".tbsCertificate.validity."); - _gnutls_str_cat(name, sizeof(name), when); - _gnutls_str_cat(name, sizeof(name), ".utcTime"); - len = sizeof(ttime) - 1; - result = asn1_read_value(c2, name, ttime, &len); - if (result == ASN_OK) - ctime = _gnutls_utcTime2gtime(ttime); - } - - if (result != ASN_OK) { - gnutls_assert(); - return (time_t) (-1); - } - return ctime; -} - -int _gnutls_get_version(node_asn * c2, char *root) -{ - opaque gversion[5]; - char name[1024]; - int len, result; - - _gnutls_str_cpy(name, sizeof(name), root); - _gnutls_str_cat(name, sizeof(name), ".tbsCertificate.version"); - - len = sizeof(gversion) - 1; - if ((result = asn1_read_value(c2, name, gversion, &len)) < 0) { - gnutls_assert(); - return (-1); - } - return (int) gversion[0] + 1; -} - - -/* Extracts DSA and RSA parameters from a certificate. - */ -static -int _gnutls_extract_cert_mpi_params( const char* ALGO_OID, gnutls_cert * gCert, - node_asn* c2, char* tmpstr, int tmpstr_size) { -int len, result; - - if (strcmp( ALGO_OID, "1 2 840 113549 1 1 1") == 0) { /* pkix-1 1 - RSA */ - /* params[0] is the modulus, - * params[1] is the exponent - */ - gCert->subject_pk_algorithm = GNUTLS_PK_RSA; - - len = tmpstr_size - 1; - result = - asn1_read_value - (c2, "certificate2.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", - tmpstr, &len); - - if (result != ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - if ((sizeof(gCert->params) / sizeof(MPI)) < RSA_PARAMS) { - gnutls_assert(); - /* internal error. Increase the MPIs in params */ - return GNUTLS_E_INTERNAL; - } - - if ((result = - _read_rsa_params(tmpstr, len / 8, gCert->params)) < 0) { - gnutls_assert(); - return result; - } - - return 0; - } - - if (strcmp( ALGO_OID, "1 2 840 10040 4 1") == 0) { /* pkix-1 1 - DSA */ - /* params[0] is p, - * params[1] is q, - * params[2] is q, - * params[3] is pub. - */ - gCert->subject_pk_algorithm = GNUTLS_PK_DSA; - - len = tmpstr_size - 1; - result = - asn1_read_value - (c2, "certificate2.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", - tmpstr, &len); - - if (result != ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - if ((sizeof(gCert->params) / sizeof(MPI)) < DSA_PARAMS) { - gnutls_assert(); - /* internal error. Increase the MPIs in params */ - return GNUTLS_E_INTERNAL; - } - - if ((result = - _read_dsa_pubkey(tmpstr, len / 8, gCert->params)) < 0) { - gnutls_assert(); - return result; - } - - /* Now read the parameters - */ - len = tmpstr_size - 1; - result = - asn1_read_value - (c2, "certificate2.tbsCertificate.subjectPublicKeyInfo.algorithm.parameters", - tmpstr, &len); - - if (result != ASN_OK) { - gnutls_assert(); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - if ((result = - _read_dsa_params(tmpstr, len, gCert->params)) < 0) { - gnutls_assert(); - return result; - } - - return 0; - } - - - - /* other types like DH - * currently not supported - */ - gnutls_assert(); - - _gnutls_log("CERT: ALGORITHM: %s\n", ALGO_OID); - - gCert->subject_pk_algorithm = GNUTLS_PK_UNKNOWN; - - return GNUTLS_E_INVALID_PARAMETERS; -} - - -#define X509_SIG_SIZE 1024 - -/* This function will convert a der certificate, to a format - * (structure) that gnutls can understand and use. Actually the - * important thing on this function is that it extracts the - * certificate's (public key) parameters. - */ -int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert) -{ - int result; - node_asn *c2; - opaque str[MAX_X509_CERT_SIZE]; - int len = sizeof(str); - - memset(gCert, 0, sizeof(gnutls_cert)); - - gCert->valid = 1; - gCert->cert_type = GNUTLS_CRT_X509; - - if (gnutls_set_datum(&gCert->raw, derCert.data, derCert.size) < 0) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - if (asn1_create_structure - (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2, - "certificate2") - != ASN_OK) { - gnutls_assert(); - gnutls_free_datum( &gCert->raw); - return GNUTLS_E_ASN1_ERROR; - } - - result = asn1_get_der(c2, derCert.data, derCert.size); - if (result != ASN_OK) { - /* couldn't decode DER */ - - _gnutls_log("CERT: Decoding error %d\n", result); - - gnutls_assert(); - asn1_delete_structure(c2); - gnutls_free_datum( &gCert->raw); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - len = sizeof(str) - 1; - result = - asn1_read_value - (c2, - "certificate2.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm", - str, &len); - - if (result != ASN_OK) { - gnutls_assert(); - asn1_delete_structure(c2); - gnutls_free_datum( &gCert->raw); - return GNUTLS_E_ASN1_PARSING_ERROR; - } - - if ( (result=_gnutls_extract_cert_mpi_params( str, gCert, c2, str, sizeof(str))) < 0) { - gnutls_assert(); - asn1_delete_structure(c2); - gnutls_free_datum( &gCert->raw); - return result; - } - - len = gCert->signature.size = X509_SIG_SIZE; - gCert->signature.data = gnutls_malloc( gCert->signature.size); - if (gCert->signature.data==NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - result = - asn1_read_value - (c2, "certificate2.signature", gCert->signature.data, &len); - - if ((len % 8) != 0) { - gnutls_assert(); - asn1_delete_structure(c2); - gnutls_free_datum( &gCert->raw); - gnutls_free_datum( &gCert->signature); - return GNUTLS_E_UNIMPLEMENTED_FEATURE; - } - - len /= 8; /* convert to bytes */ - gCert->signature.size = len; /* put the actual sig size */ - - - gCert->expiration_time = - _gnutls_get_time(c2, "certificate2", "notAfter"); - gCert->activation_time = - _gnutls_get_time(c2, "certificate2", "notBefore"); - gCert->version = _gnutls_get_version(c2, "certificate2"); - - if ((result = - _gnutls_get_ext_type(c2, - "certificate2.tbsCertificate.extensions", - gCert)) < 0) { - gnutls_assert(); - asn1_delete_structure(c2); - gnutls_free_datum( &gCert->raw); - return result; - } - - asn1_delete_structure(c2); - - - gCert->valid = 0; /* if we got until here - * the certificate is valid. - */ - - return 0; - -} - -/* Returns 0 if it's ok to use the KXAlgorithm with this cert - * (using KeyUsage field). - */ -int _gnutls_check_x509_key_usage(const gnutls_cert * cert, - KXAlgorithm alg) -{ - if (_gnutls_map_kx_get_cred(alg) == GNUTLS_CRD_CERTIFICATE) { - switch (alg) { - case GNUTLS_KX_RSA: - if (cert->keyUsage != 0) { - if (! - (cert-> - keyUsage & GNUTLS_X509KEY_KEY_ENCIPHERMENT)) - return - GNUTLS_E_X509_KEY_USAGE_VIOLATION; - else - return 0; - } - return 0; - case GNUTLS_KX_DHE_RSA: - case GNUTLS_KX_DHE_DSS: - if (cert->keyUsage != 0) { - if (! - (cert-> - keyUsage & GNUTLS_X509KEY_DIGITAL_SIGNATURE)) - return - GNUTLS_E_X509_KEY_USAGE_VIOLATION; - else - return 0; - } - return 0; - default: - gnutls_assert(); - return GNUTLS_E_X509_KEY_USAGE_VIOLATION; - } - } - return 0; -} /* returns the KX algorithms that are supported by a * certificate. (Eg a certificate with RSA params, supports @@ -1332,7 +175,16 @@ int _gnutls_cert_supported_kx(const gnutls_cert * cert, KXAlgorithm ** alg, for (kx = 0; kx < MAX_KX_ALGOS; kx++) { pk = _gnutls_map_pk_get_pk(kx); if (pk == cert->subject_pk_algorithm) { - if (_gnutls_check_x509_key_usage(cert, kx) == 0) { + if (cert->cert_type==GNUTLS_CRT_X509) { + /* then check key usage */ + if (_gnutls_check_x509_key_usage(cert, kx) == 0) { + kxlist[i] = kx; + i++; + } + } else if ( cert->cert_type==GNUTLS_CRT_OPENPGP) { + /* FIXME: something like key usage + * should be added + */ kxlist[i] = kx; i++; } @@ -1453,3 +305,37 @@ void gnutls_certificate_server_set_select_func(GNUTLS_STATE state, { state->gnutls_internals.server_cert_callback = func; } + +/** + * gnutls_certificate_verify_peers - This function returns the peer's certificate verification status + * @state: is a gnutls state + * + * This function will try to verify the peer's certificate and return it's status (TRUSTED, EXPIRED etc.). + * The return value (status) should be one of the CertificateStatus enumerated elements. + * However you must also check the peer's name in order to check if the verified certificate belongs to the + * actual peer. Returns a negative error code in case of an error, or GNUTLS_CERT_NONE if no certificate was sent. + * + **/ +int gnutls_certificate_verify_peers(GNUTLS_STATE state) +{ + CERTIFICATE_AUTH_INFO info; + + CHECK_AUTH(GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST); + + info = _gnutls_get_auth_info(state); + if (info == NULL) + return GNUTLS_E_INVALID_REQUEST; + + if (info->raw_certificate_list == NULL || info->ncerts == 0) + return GNUTLS_CERT_NONE; + + switch( gnutls_cert_type_get( state)) { + case GNUTLS_CRT_X509: + return _gnutls_x509_cert_verify_peers( state); + case GNUTLS_CRT_OPENPGP: + /* FIX THIS */ +/* return _gnutls_openpgp_cert_verify_peers( state); */ + default: + return GNUTLS_E_INVALID_REQUEST; + } +} diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h index ad08db483a..54e04103d7 100644 --- a/lib/gnutls_cert.h +++ b/lib/gnutls_cert.h @@ -34,7 +34,7 @@ typedef struct gnutls_cert { gnutls_datum signature; - opaque fingerprint[20]; + opaque fingerprint[20]; time_t expiration_time; time_t activation_time; @@ -82,14 +82,7 @@ struct GNUTLS_STATE_INT; /* because GNUTLS_STATE is not defined when this file i int _gnutls_cert_supported_kx( const gnutls_cert* cert, KXAlgorithm **alg, int *alg_size); PKAlgorithm _gnutls_map_pk_get_pk(KXAlgorithm kx_algorithm); -int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert); -#define MAX_INT_DIGITS 4 -void _gnutls_int2str(int k, char* data); -int _gnutls_get_name_type( node_asn *rasn, char *root, gnutls_dn * dn); void gnutls_free_cert(gnutls_cert cert); -int _gnutls_check_x509_key_usage( const gnutls_cert * cert, KXAlgorithm alg); -int _gnutls_get_version(node_asn * c2, char *root); -time_t _gnutls_get_time(node_asn * c2, char *root, char *when); #endif diff --git a/lib/gnutls_int_compat.c b/lib/gnutls_int_compat.c index f402b66095..5da43995b1 100644 --- a/lib/gnutls_int_compat.c +++ b/lib/gnutls_int_compat.c @@ -8,51 +8,6 @@ #ifdef GNUTLS_BACKWARDS_COMPATIBLE -/* used in 0.3.x */ -int gnutls_anon_set_server_cred( GNUTLS_ANON_SERVER_CREDENTIALS res, int dh_bits) { - return 0; -} - -/* used in 0.3.x */ -int gnutls_check_pending( GNUTLS_STATE state) { - return gnutls_record_check_pending( state); -} - -/* used in 0.3.x */ -void gnutls_x509pki_set_dh_bits(GNUTLS_STATE state, int bits) { - gnutls_dh_set_bits( state, bits); -} - -/* used in 0.3.x */ -int gnutls_anon_server_get_dh_bits(GNUTLS_STATE state) -{ - return gnutls_dh_get_bits( state); -} - -/* used in 0.3.x */ -int gnutls_anon_client_get_dh_bits(GNUTLS_STATE state) -{ - return gnutls_dh_get_bits( state); -} - -/* used in 0.3.x */ -int gnutls_set_max_handshake_data_buffer_size( GNUTLS_STATE state) { - return 0; -} - -GNUTLS_BulkCipherAlgorithm gnutls_cipher_get_algo( GNUTLS_STATE state) { - return gnutls_cipher_get( state); -} -GNUTLS_KXAlgorithm gnutls_kx_get_algo( GNUTLS_STATE state) { - return gnutls_kx_get( state); -} - -GNUTLS_MACAlgorithm gnutls_mac_get_algo( GNUTLS_STATE state) { - return gnutls_mac_get( state); -} - -GNUTLS_CompressionMethod gnutls_compression_get_algo( GNUTLS_STATE state) { - return gnutls_compression_get( state); -} +/* nothing here */ #endif /* GNUTLS_BACKWARDS_COMPATIBLE */ diff --git a/lib/gnutls_session_pack.c b/lib/gnutls_session_pack.c index 6c723f4688..a76bce3393 100644 --- a/lib/gnutls_session_pack.c +++ b/lib/gnutls_session_pack.c @@ -28,11 +28,11 @@ #include <gnutls_num.h> #define PACK_HEADER_SIZE 1 -int _gnutls_pack_x509pki_auth_info( CERTIFICATE_AUTH_INFO info, +int _gnutls_pack_certificate_auth_info( CERTIFICATE_AUTH_INFO info, gnutls_datum * packed_session); -int _gnutls_unpack_x509pki_auth_info(CERTIFICATE_AUTH_INFO info, +int _gnutls_unpack_certificate_auth_info(CERTIFICATE_AUTH_INFO info, const gnutls_datum * packed_session); -static int _gnutls_pack_x509pki_auth_info_size( CERTIFICATE_AUTH_INFO info); +static int _gnutls_pack_certificate_auth_info_size( CERTIFICATE_AUTH_INFO info); /* Since auth_info structures contain malloced data, this function @@ -106,7 +106,7 @@ int _gnutls_session_pack(GNUTLS_STATE state, gnutls_datum * packed_session) return GNUTLS_E_INVALID_PARAMETERS; ret = - _gnutls_pack_x509pki_auth_info(info, + _gnutls_pack_certificate_auth_info(info, packed_session); if (ret < 0) { gnutls_assert(); @@ -152,7 +152,7 @@ int _gnutls_session_size( GNUTLS_STATE state) if (info == NULL) return GNUTLS_E_INVALID_PARAMETERS; - pack_size += _gnutls_pack_x509pki_auth_info_size( info); + pack_size += _gnutls_pack_certificate_auth_info_size( info); } break; } @@ -260,7 +260,7 @@ int _gnutls_session_unpack(GNUTLS_STATE state, sizeof(CERTIFICATE_AUTH_INFO_INT); ret = - _gnutls_unpack_x509pki_auth_info(state-> + _gnutls_unpack_certificate_auth_info(state-> gnutls_key-> auth_info, packed_session); @@ -308,11 +308,11 @@ int _gnutls_session_unpack(GNUTLS_STATE state, return 0; } -int _gnutls_pack_x509pki_auth_info( CERTIFICATE_AUTH_INFO info, +int _gnutls_pack_certificate_auth_info( CERTIFICATE_AUTH_INFO info, gnutls_datum * packed_session) { uint32 pos, i; - packed_session->size = _gnutls_pack_x509pki_auth_info_size( info); + packed_session->size = _gnutls_pack_certificate_auth_info_size( info); packed_session->data[0] = GNUTLS_CRD_CERTIFICATE; WRITEuint32( packed_session->size-PACK_HEADER_SIZE-sizeof(uint32), &packed_session->data[PACK_HEADER_SIZE]); @@ -335,7 +335,7 @@ int _gnutls_pack_x509pki_auth_info( CERTIFICATE_AUTH_INFO info, return 0; } -static int _gnutls_pack_x509pki_auth_info_size( CERTIFICATE_AUTH_INFO info) +static int _gnutls_pack_certificate_auth_info_size( CERTIFICATE_AUTH_INFO info) { uint32 pack_size = sizeof(CERTIFICATE_AUTH_INFO_INT); int i; @@ -351,7 +351,7 @@ static int _gnutls_pack_x509pki_auth_info_size( CERTIFICATE_AUTH_INFO info) } -int _gnutls_unpack_x509pki_auth_info(CERTIFICATE_AUTH_INFO info, +int _gnutls_unpack_certificate_auth_info(CERTIFICATE_AUTH_INFO info, const gnutls_datum * packed_session) { int ret, i, pos, j; diff --git a/lib/gnutls_ui.h b/lib/gnutls_ui.h index 78ec695402..6a5e97eb5a 100644 --- a/lib/gnutls_ui.h +++ b/lib/gnutls_ui.h @@ -81,7 +81,7 @@ const gnutls_datum *gnutls_certificate_get_ours(GNUTLS_STATE state); int gnutls_certificate_get_ours_index(GNUTLS_STATE state); int gnutls_certificate_client_get_request_status( GNUTLS_STATE); -int gnutls_x509pki_verify_peers( GNUTLS_STATE); +int gnutls_certificate_verify_peers( GNUTLS_STATE); int gnutls_b64_encode_fmt( const char* msg, const gnutls_datum *data, char* result, int* result_size); int gnutls_b64_decode_fmt( const gnutls_datum *b64_data, char* result, int* result_size); diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c index 472f01c9a6..59dac2d218 100644 --- a/lib/gnutls_x509.c +++ b/lib/gnutls_x509.c @@ -38,7 +38,279 @@ #include <x509_extensions.h> #include <gnutls_state.h> #include <gnutls_pk.h> +#include <gnutls_str.h> #include <debug.h> +#include <x509_b64.h> +#include <gnutls_privkey.h> +#include <gnutls_x509.h> + +/* + * some x509 certificate parsing functions. + */ + +#define _READ(a, aa, b, c, d, e, res, f) \ + result = _IREAD(a, aa, sizeof(aa), b, c, d, e, res, sizeof(res)-1, f); \ + if (result<0) return result; \ + if (result==1) continue + + +static int _IREAD(node_asn * rasn, char *name3, int name3_size, char *rstr, char *OID, + char *ANAME, char *TYPE, char *res, int res_size, int CHOICE) +{ + char name2[256]; + int result, len; + char str[1024]; + node_asn *tmpasn; + + if (strcmp(rstr, OID) == 0) { + + _gnutls_str_cpy(str, sizeof(str), "PKIX1Implicit88."); + _gnutls_str_cat(str, sizeof(str), ANAME); + _gnutls_str_cpy(name2, sizeof(name2), "temp-structure-"); + _gnutls_str_cat(name2, sizeof(name2), TYPE); + + if ((result = + asn1_create_structure(_gnutls_get_pkix(), str, + &tmpasn, name2)) != ASN_OK) { + gnutls_assert(); + return GNUTLS_E_ASN1_ERROR; + } + + len = sizeof(str) -1; + if ((result = + asn1_read_value(rasn, name3, str, &len)) != ASN_OK) { + asn1_delete_structure(tmpasn); + return 1; + } + + if ((result = asn1_get_der(tmpasn, str, len)) != ASN_OK) { + asn1_delete_structure(tmpasn); + return 1; + } + _gnutls_str_cpy(name3, name3_size, name2); + + len = sizeof(str) - 1; + if ((result = asn1_read_value(tmpasn, name3, str, &len)) != ASN_OK) { /* CHOICE */ + asn1_delete_structure(tmpasn); + return 1; + } + + if (CHOICE == 0) { + str[len] = 0; + /* strlen(str) < res_size, checked above */ + _gnutls_str_cpy(res, res_size, str); + + } else { /* CHOICE */ + str[len] = 0; + _gnutls_str_cat(name3, name3_size, "."); + _gnutls_str_cat(name3, name3_size, str); + len = sizeof(str) - 1; + + if ((result = + asn1_read_value(tmpasn, name3, str, + &len)) != ASN_OK) { + asn1_delete_structure(tmpasn); + return 1; + } + str[len] = 0; + if ( len < res_size) + _gnutls_str_cpy(res, res_size, str); + } + asn1_delete_structure(tmpasn); + + } + return 0; +} + +/* this function will convert up to 3 digit + * numbers to characters. + */ +void _gnutls_int2str(int k, char *data) +{ + if (k > 999) + data[0] = 0; + else + sprintf(data, "%d", k); +} + +/* This function will attempt to read a Name + * ASN.1 structure. (Taken from Fabio's samples!) + * + * FIXME: These functions need carefull auditing + * (they're complex enough) + * --nmav + */ +int _gnutls_x509_get_name_type(node_asn * rasn, char *root, gnutls_DN * dn) +{ + int k, k2, result, len; + char name[128], str[1024], name2[128], counter[MAX_INT_DIGITS], + name3[128]; + + k = 0; + do { + k++; + + _gnutls_str_cpy(name, sizeof(name), root); + _gnutls_str_cat(name, sizeof(name), ".rdnSequence.?"); + _gnutls_int2str(k, counter); + _gnutls_str_cat(name, sizeof(name), counter); + + len = sizeof(str) - 1; + + result = asn1_read_value(rasn, name, str, &len); + + /* move to next + */ + if (result == ASN_ELEMENT_NOT_FOUND) + break; + if (result != ASN_VALUE_NOT_FOUND) { + gnutls_assert(); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + k2 = 0; + do { + k2++; + + _gnutls_str_cpy(name2, sizeof(name2), name); + _gnutls_str_cat(name2, sizeof(name2), ".?"); + _gnutls_int2str(k2, counter); + _gnutls_str_cat(name2, sizeof(name2), counter); + + len = sizeof(str) - 1; + result = asn1_read_value(rasn, name2, str, &len); + + if (result == ASN_ELEMENT_NOT_FOUND) + break; + if (result != ASN_VALUE_NOT_FOUND) { + gnutls_assert(); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + _gnutls_str_cpy(name3, sizeof(name3), name2); + _gnutls_str_cat(name3, sizeof(name3), ".type"); + + len = sizeof(str) - 1; + result = asn1_read_value(rasn, name3, str, &len); + + if (result == ASN_ELEMENT_NOT_FOUND) + break; + else if (result != ASN_OK) { + gnutls_assert(); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + _gnutls_str_cpy(name3, sizeof(name3), name2); + _gnutls_str_cat(name3, sizeof(name3), ".value"); + + if (result == ASN_OK) { +#ifdef DEBUG +# warning " FIX COUNTRY HERE" +#endif + _READ(rasn, name3, str, "2 5 4 6", + "X520OrganizationName", + "countryName", dn->country, 1); + _READ(rasn, name3, str, "2 5 4 10", + "X520OrganizationName", + "OrganizationName", dn->organization, + 1); + _READ(rasn, name3, str, "2 5 4 11", + "X520OrganizationalUnitName", + "OrganizationalUnitName", + dn->organizational_unit_name, 1); + _READ(rasn, name3, str, "2 5 4 3", + "X520CommonName", "CommonName", + dn->common_name, 1); + _READ(rasn, name3, str, "2 5 4 7", + "X520LocalityName", "LocalityName", + dn->locality_name, 1); + _READ(rasn, name3, str, "2 5 4 8", + "X520StateOrProvinceName", + "StateOrProvinceName", + dn->state_or_province_name, 1); + _READ(rasn, name3, str, + "1 2 840 113549 1 9 1", "Pkcs9email", + "emailAddress", dn->email, 0); + } + } while (1); + } while (1); + + if (result == ASN_ELEMENT_NOT_FOUND) + return 0; + else + return GNUTLS_E_ASN1_PARSING_ERROR; +} + + + +#define MAX_TIME 1024 +time_t _gnutls_x509_get_time(node_asn * c2, char *root, char *when) +{ + opaque ttime[MAX_TIME]; + char name[1024]; + time_t ctime; + int len, result; + + _gnutls_str_cpy(name, sizeof(name), root); + _gnutls_str_cat(name, sizeof(name), ".tbsCertificate.validity."); + _gnutls_str_cat(name, sizeof(name), when); + + len = sizeof(ttime) - 1; + if ((result = asn1_read_value(c2, name, ttime, &len)) < 0) { + gnutls_assert(); + return (time_t) (-1); + } + + /* CHOICE */ + _gnutls_str_cpy(name, sizeof(name), root); + + if (strcmp(ttime, "GeneralizedTime") == 0) { + + _gnutls_str_cat(name, sizeof(name), ".tbsCertificate.validity."); + _gnutls_str_cat(name, sizeof(name), when); + _gnutls_str_cat(name, sizeof(name), ".generalTime"); + len = sizeof(ttime) - 1; + result = asn1_read_value(c2, name, ttime, &len); + if (result == ASN_OK) + ctime = _gnutls_generalTime2gtime(ttime); + } else { /* UTCTIME */ + + _gnutls_str_cat(name, sizeof(name), ".tbsCertificate.validity."); + _gnutls_str_cat(name, sizeof(name), when); + _gnutls_str_cat(name, sizeof(name), ".utcTime"); + len = sizeof(ttime) - 1; + result = asn1_read_value(c2, name, ttime, &len); + if (result == ASN_OK) + ctime = _gnutls_utcTime2gtime(ttime); + } + + if (result != ASN_OK) { + gnutls_assert(); + return (time_t) (-1); + } + return ctime; +} + +int _gnutls_x509_get_version(node_asn * c2, char *root) +{ + opaque gversion[5]; + char name[1024]; + int len, result; + + _gnutls_str_cpy(name, sizeof(name), root); + _gnutls_str_cat(name, sizeof(name), ".tbsCertificate.version"); + + len = sizeof(gversion) - 1; + if ((result = asn1_read_value(c2, name, gversion, &len)) < 0) { + gnutls_assert(); + return (-1); + } + return (int) gversion[0] + 1; +} + + + + /** * gnutls_x509_extract_dn - This function parses an RDN sequence @@ -71,7 +343,7 @@ int gnutls_x509_extract_dn(const gnutls_datum * idn, gnutls_dn * rdn) return GNUTLS_E_ASN1_PARSING_ERROR; } - result = _gnutls_get_name_type(dn, "dn", rdn); + result = _gnutls_x509_get_name_type(dn, "dn", rdn); asn1_delete_structure(dn); if (result < 0) { @@ -122,7 +394,7 @@ int gnutls_x509_extract_certificate_dn(const gnutls_datum * cert, return GNUTLS_E_ASN1_PARSING_ERROR; } if ((result = - _gnutls_get_name_type(c2, + _gnutls_x509_get_name_type(c2, "certificate2.tbsCertificate.subject", ret)) < 0) { gnutls_assert(); @@ -173,7 +445,7 @@ int gnutls_x509_extract_certificate_issuer_dn(const gnutls_datum * cert, return GNUTLS_E_ASN1_PARSING_ERROR; } if ((result = - _gnutls_get_name_type(c2, + _gnutls_x509_get_name_type(c2, "certificate2.tbsCertificate.issuer", ret)) < 0) { gnutls_assert(); @@ -269,7 +541,7 @@ time_t gnutls_x509_extract_certificate_activation_time(const return -1; } - ret = _gnutls_get_time(c2, "certificate2", "notBefore"); + ret = _gnutls_x509_get_time(c2, "certificate2", "notBefore"); asn1_delete_structure(c2); @@ -311,7 +583,7 @@ time_t gnutls_x509_extract_certificate_expiration_time(const return -1; } - ret = _gnutls_get_time(c2, "certificate2", "notAfter"); + ret = _gnutls_x509_get_time(c2, "certificate2", "notAfter"); asn1_delete_structure(c2); @@ -349,7 +621,7 @@ int gnutls_x509_extract_certificate_version(const gnutls_datum * cert) return GNUTLS_E_ASN1_PARSING_ERROR; } - result = _gnutls_get_version(c2, "certificate2"); + result = _gnutls_x509_get_version(c2, "certificate2"); asn1_delete_structure(c2); @@ -359,8 +631,8 @@ int gnutls_x509_extract_certificate_version(const gnutls_datum * cert) #define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) gnutls_free_cert(peer_certificate_list[x]) -/** - * gnutls_x509pki_verify_peers - This function returns the peer's certificate status +/*- + * _gnutls_x509_cert_verify_peers - This function returns the peer's certificate status * @state: is a gnutls state * * This function will try to verify the peer's certificate and return it's status (TRUSTED, EXPIRED etc.). @@ -368,8 +640,8 @@ int gnutls_x509_extract_certificate_version(const gnutls_datum * cert) * However you must also check the peer's name in order to check if the verified certificate belongs to the * actual peer. Returns a negative error code in case of an error, or GNUTLS_CERT_NONE if no certificate was sent. * - **/ -int gnutls_x509pki_verify_peers(GNUTLS_STATE state) + -*/ +int _gnutls_x509_cert_verify_peers(GNUTLS_STATE state) { CERTIFICATE_AUTH_INFO info; const GNUTLS_CERTIFICATE_CREDENTIALS cred; @@ -440,7 +712,7 @@ int gnutls_x509pki_verify_peers(GNUTLS_STATE state) #define CLEAR_CERTS_CA for(x=0;x<peer_certificate_list_size;x++) gnutls_free_cert(peer_certificate_list[x]); \ for(x=0;x<ca_certificate_list_size;x++) gnutls_free_cert(ca_certificate_list[x]) /** - * gnutls_x509pki_verify_certificate - This function verifies given certificate list + * 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 @@ -454,7 +726,7 @@ int gnutls_x509pki_verify_peers(GNUTLS_STATE state) * actual peer. Returns a negative error code in case of an error. * **/ -int gnutls_x509pki_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) +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) { CertificateStatus verify; gnutls_cert *peer_certificate_list; @@ -583,3 +855,894 @@ int gnutls_x509_extract_certificate_serial(const gnutls_datum * cert, char* resu return 0; } + + +/* + * Read certificates and private keys, from files, memory etc. + */ + +/* returns error if the certificate has different algorithm than + * the given key parameters. + */ +static int _gnutls_check_key_cert_match( GNUTLS_CERTIFICATE_CREDENTIALS res) { + if (res->pkey->pk_algorithm != res->cert_list[0]->subject_pk_algorithm) { + gnutls_assert(); + return GNUTLS_E_CERTIFICATE_KEY_MISMATCH; + } + return 0; +} + +#define MAX_FILE_SIZE 100*1024 +#define CERT_SEP "-----BEGIN" + +/* Reads a base64 encoded certificate from memory + */ +static int read_cert_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *cert, int cert_size) +{ + int siz, i, siz2; + opaque *b64; + const char *ptr; + gnutls_datum tmp; + int ret; + + /* allocate space for the certificate to add + */ + res->cert_list = gnutls_realloc( res->cert_list, (1+res->ncerts)*sizeof(gnutls_cert*)); + if (res->cert_list==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + res->cert_list_length = gnutls_realloc( res->cert_list_length, + (1+res->ncerts)*sizeof(int)); + if (res->cert_list_length==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + + ptr = cert; + siz = cert_size; + i = 1; + + res->cert_list[res->ncerts] = NULL; + + do { + siz2 = _gnutls_fbase64_decode(ptr, siz, &b64); + siz -= siz2; /* FIXME: this is not enough + */ + + if (siz2 < 0) { + gnutls_assert(); + gnutls_free(b64); + return GNUTLS_E_PARSING_ERROR; + } + + + res->cert_list[res->ncerts] = + (gnutls_cert *) gnutls_realloc(res-> + cert_list[res->ncerts], + i * + sizeof(gnutls_cert)); + + if (res->cert_list[res->ncerts] == NULL) { + gnutls_assert(); + gnutls_free(b64); + return GNUTLS_E_MEMORY_ERROR; + } + /* set defaults to zero + */ + memset(&res->cert_list[res->ncerts][i - 1], 0, + sizeof(gnutls_cert)); + + tmp.data = b64; + tmp.size = siz2; + + if ((ret = + _gnutls_x509_cert2gnutls_cert(&res-> + cert_list[res->ncerts][i - 1], + tmp)) < 0) { + gnutls_free(b64); + gnutls_assert(); + return ret; + } + gnutls_free(b64); + + /* now we move ptr after the pem header */ + ptr = strstr(ptr, CERT_SEP); + if (ptr!=NULL) + ptr++; + + i++; + } while ((ptr = strstr(ptr, CERT_SEP)) != NULL); + + res->cert_list_length[res->ncerts] = i - 1; + + res->ncerts++; + + return 0; +} + +/* Reads a base64 encoded CA list from memory + * This is to be called once. + */ +static int read_ca_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *ca, int ca_size) +{ + int siz, siz2, i; + opaque *b64; + const char *ptr; + int ret; + gnutls_datum tmp; + + siz = ca_size; + + ptr = ca; + + i = res->x509_ncas + 1; + + do { + siz2 = _gnutls_fbase64_decode(ptr, siz, &b64); + siz -= siz2; /* FIXME: this is not enough + */ + + if (siz2 < 0) { + gnutls_assert(); + gnutls_free(b64); + return GNUTLS_E_PARSING_ERROR; + } + + res->x509_ca_list = + (gnutls_cert *) gnutls_realloc(res->x509_ca_list, + i * + sizeof(gnutls_cert)); + if (res->x509_ca_list == NULL) { + gnutls_assert(); + gnutls_free(b64); + return GNUTLS_E_MEMORY_ERROR; + } + memset(&res->x509_ca_list[i - 1], 0, sizeof(gnutls_cert)); + + tmp.data = b64; + tmp.size = siz2; + + if ((ret = + _gnutls_x509_cert2gnutls_cert(&res->x509_ca_list[i - 1], + tmp)) < 0) { + gnutls_assert(); + gnutls_free(b64); + return ret; + } + gnutls_free(b64); + + /* now we move ptr after the pem header */ + ptr = strstr(ptr, CERT_SEP); + if (ptr!=NULL) + ptr++; + + i++; + } while ((ptr = strstr(ptr, CERT_SEP)) != NULL); + + res->x509_ncas = i - 1; + + + + return 0; +} + + +/* Reads a PEM encoded PKCS-1 RSA private key from memory + * 2002-01-26: Added ability to read DSA keys. + */ +static int read_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const char *key, int key_size) +{ + int siz, ret; + opaque *b64; + gnutls_datum tmp; + PKAlgorithm pk; + + /* allocate space for the pkey list + */ + res->pkey = gnutls_realloc( res->pkey, (res->ncerts+1)*sizeof(gnutls_private_key)); + if (res->pkey==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + /* read PKCS-1 private key */ + siz = key_size; + + /* If we find the "DSA PRIVATE" string in the + * pem encoded certificate then it's a DSA key. + */ + if (strstr( key, "DSA PRIVATE")!=NULL) + pk = GNUTLS_PK_DSA; + else + pk = GNUTLS_PK_RSA; + + siz = _gnutls_fbase64_decode(key, siz, &b64); + + if (siz < 0) { + gnutls_assert(); + gnutls_free(b64); + return GNUTLS_E_PARSING_ERROR; + } + + tmp.data = b64; + tmp.size = siz; + + switch (pk) { /* decode the key */ + case GNUTLS_PK_RSA: + if ((ret = + _gnutls_PKCS1key2gnutlsKey(&res->pkey[res->ncerts], + tmp)) < 0) { + gnutls_assert(); + gnutls_free(b64); + return ret; + } + break; + case GNUTLS_PK_DSA: + if ((ret = + _gnutls_DSAkey2gnutlsKey(&res->pkey[res->ncerts], + tmp)) < 0) { + gnutls_assert(); + gnutls_free(b64); + return ret; + } + break; + } + gnutls_free(b64); + + return 0; +} + + +/* Reads a base64 encoded certificate file + */ +static int read_cert_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *certfile) +{ + int siz; + char x[MAX_FILE_SIZE]; + FILE *fd1; + + fd1 = fopen(certfile, "r"); + if (fd1 == NULL) + return GNUTLS_E_UNKNOWN_ERROR; + + siz = fread(x, 1, sizeof(x), fd1); + fclose(fd1); + + x[siz-1] = 0; + + return read_cert_mem( res, x, siz); + +} + +/* Reads a base64 encoded CA file (file contains multiple certificate + * authorities). This is to be called once. + */ +static int read_ca_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *cafile) +{ + int siz; + char x[MAX_FILE_SIZE]; + FILE *fd1; + + fd1 = fopen(cafile, "r"); + if (fd1 == NULL) { + gnutls_assert(); + return GNUTLS_E_UNKNOWN_ERROR; + } + + siz = fread(x, 1, sizeof(x), fd1); + fclose(fd1); + + x[siz-1] = 0; + + return read_ca_mem( res, x, siz); +} + + +/* Reads a PEM encoded PKCS-1 RSA private key file + */ +static int read_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *keyfile) +{ + int siz; + char x[MAX_FILE_SIZE]; + FILE *fd2; + + fd2 = fopen(keyfile, "r"); + if (fd2 == NULL) + return GNUTLS_E_UNKNOWN_ERROR; + + siz = fread(x, 1, sizeof(x), fd2); + fclose(fd2); + + x[siz-1] = 0; + + return read_key_mem( res, x, siz); +} + + +/** + * gnutls_certificate_set_x509_key_file - Used to set keys in a GNUTLS_CERTIFICATE_CREDENTIALS structure + * @res: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure. + * @CERTFILE: is a PEM encoded file containing the certificate list (path) for + * the specified private key + * @KEYFILE: is a PEM encoded file containing a private key + * + * This function sets a certificate/private key pair in the + * GNUTLS_CERTIFICATE_CREDENTIALS structure. This function may be called + * more than once (in case multiple keys/certificates exist for the + * server). + * + * Currently only PKCS-1 PEM encoded RSA and DSA private keys are accepted by + * this function. + * + **/ +int gnutls_certificate_set_x509_key_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *CERTFILE, + char *KEYFILE) +{ + int ret; + + /* this should be first + */ + if ((ret = read_key_file(res, KEYFILE)) < 0) + return ret; + + if ((ret = read_cert_file(res, CERTFILE)) < 0) + return ret; + + if ((ret=_gnutls_check_key_cert_match( res)) < 0) { + gnutls_assert(); + return ret; + } + + return 0; +} + +static int generate_rdn_seq( GNUTLS_CERTIFICATE_CREDENTIALS res) { +gnutls_datum tmp; +int ret, size, i; +opaque *pdata; + + /* Generate the RDN sequence + * This will be sent to clients when a certificate + * request message is sent. + */ + + /* FIXME: in case of a client it is not needed + * to do that. This would save time and memory. + * However we don't have that information available + * here. + */ + + size = 0; + for (i = 0; i < res->x509_ncas; i++) { + if ((ret = _gnutls_find_dn(&tmp, &res->x509_ca_list[i])) < 0) { + gnutls_assert(); + return ret; + } + size += (2 + tmp.size); + } + + if (res->x509_rdn_sequence.data != NULL) + gnutls_free( res->x509_rdn_sequence.data); + + res->x509_rdn_sequence.data = gnutls_malloc(size); + if (res->x509_rdn_sequence.data == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + res->x509_rdn_sequence.size = size; + + pdata = res->x509_rdn_sequence.data; + + for (i = 0; i < res->x509_ncas; i++) { + if ((ret = _gnutls_find_dn(&tmp, &res->x509_ca_list[i])) < 0) { + gnutls_free(res->x509_rdn_sequence.data); + res->x509_rdn_sequence.size = 0; + res->x509_rdn_sequence.data = NULL; + gnutls_assert(); + return ret; + } + WRITEdatum16(pdata, tmp); + pdata += (2 + tmp.size); + } + + return 0; +} + +/** + * gnutls_certificate_set_x509_trust_mem - Used to add trusted CAs in a GNUTLS_CERTIFICATE_CREDENTIALS structure + * @res: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure. + * @CA: is a PEM encoded list of trusted CAs + * @CRL: is a PEM encoded list of CRLs (ignored for now) + * + * This function adds the trusted CAs in order to verify client + * certificates. This function may be called multiple times. + * + **/ +int gnutls_certificate_set_x509_trust_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const gnutls_datum *CA, + const gnutls_datum *CRL) +{ + int ret; + + if ((ret = read_ca_mem(res, CA->data, CA->size)) < 0) + return ret; + + if ((ret = generate_rdn_seq(res)) < 0) + return ret; + + return 0; +} + +/** + * gnutls_certificate_set_x509_trust_file - Used to add trusted CAs in a GNUTLS_CERTIFICATE_CREDENTIALS structure + * @res: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure. + * @CAFILE: is a PEM encoded file containing trusted CAs + * @CRLFILE: is a PEM encoded file containing CRLs (ignored for now) + * + * This function sets the trusted CAs in order to verify client + * certificates. This function may be called multiple times. + * + **/ +int gnutls_certificate_set_x509_trust_file(GNUTLS_CERTIFICATE_CREDENTIALS res, char *CAFILE, + char *CRLFILE) +{ + int ret; + + if ((ret = read_ca_file(res, CAFILE)) < 0) + return ret; + + if ((ret = generate_rdn_seq(res)) < 0) + return ret; + + return 0; +} + + +/** + * gnutls_certificate_set_x509_key_mem - Used to set keys in a GNUTLS_CERTIFICATE_CREDENTIALS structure + * @res: is an &GNUTLS_CERTIFICATE_CREDENTIALS structure. + * @CERT: contains a PEM encoded certificate list (path) for + * the specified private key + * @KEY: is a PEM encoded private key + * + * This function sets a certificate/private key pair in the + * GNUTLS_CERTIFICATE_CREDENTIALS structure. This function may be called + * more than once (in case multiple keys/certificates exist for the + * server). + * + * Currently are supported: RSA PKCS-1 PEM encoded private keys, + * pem encoded DSA private keys. + * + **/ +int gnutls_certificate_set_x509_key_mem(GNUTLS_CERTIFICATE_CREDENTIALS res, const gnutls_datum* CERT, + const gnutls_datum* KEY) +{ + int ret; + + /* this should be first + */ + if ((ret = read_key_mem( res, KEY->data, KEY->size)) < 0) + return ret; + + if ((ret = read_cert_mem( res, CERT->data, CERT->size)) < 0) + return ret; + + if ((ret=_gnutls_check_key_cert_match( res)) < 0) { + gnutls_assert(); + return ret; + } + + return 0; +} + + +static int _read_rsa_params(opaque * der, int dersize, MPI * params) +{ + opaque str[MAX_PARAMETER_SIZE]; + int result; + node_asn *spk; + + if (asn1_create_structure + (_gnutls_get_gnutls_asn(), "GNUTLS.RSAPublicKey", &spk, + "rsa_public_key") != ASN_OK) { + gnutls_assert(); + return GNUTLS_E_ASN1_ERROR; + } + + result = asn1_get_der(spk, der, dersize); + + if (result != ASN_OK) { + gnutls_assert(); + asn1_delete_structure(spk); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + + if ( (result=_gnutls_x509_read_int( spk, "rsa_public_key.modulus", + str, sizeof(str)-1, ¶ms[0])) < 0) { + gnutls_assert(); + asn1_delete_structure(spk); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + if ( (result=_gnutls_x509_read_int( spk, "rsa_public_key.publicExponent", + str, sizeof(str)-1, ¶ms[1])) < 0) { + gnutls_assert(); + _gnutls_mpi_release(¶ms[0]); + asn1_delete_structure(spk); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + asn1_delete_structure(spk); + + return 0; + +} + + +/* reads p,q and g + * from the certificate + * params[0-2] + */ +static int _read_dsa_params(opaque * der, int dersize, MPI * params) +{ + opaque str[MAX_PARAMETER_SIZE]; + int result; + node_asn *spk; + + if (asn1_create_structure + (_gnutls_get_pkix(), "PKIX1Implicit88.Dss-Parms", &spk, + "dsa_parms") != ASN_OK) { + gnutls_assert(); + return GNUTLS_E_ASN1_ERROR; + } + + result = asn1_get_der(spk, der, dersize); + + if (result != ASN_OK) { + gnutls_assert(); + asn1_delete_structure(spk); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + /* FIXME: If the parameters are not included in the certificate + * then the issuer's parameters should be used. + */ + + /* Read p */ + + if ( (result=_gnutls_x509_read_int( spk, "dsa_parms.p", str, sizeof(str)-1, ¶ms[0])) < 0) { + gnutls_assert(); + asn1_delete_structure(spk); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + /* Read q */ + + if ( (result=_gnutls_x509_read_int( spk, "dsa_parms.q", str, sizeof(str)-1, ¶ms[1])) < 0) { + gnutls_assert(); + asn1_delete_structure(spk); + _gnutls_mpi_release(¶ms[0]); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + /* Read g */ + + if ( (result=_gnutls_x509_read_int( spk, "dsa_parms.g", str, sizeof(str)-1, ¶ms[2])) < 0) { + gnutls_assert(); + asn1_delete_structure(spk); + _gnutls_mpi_release(¶ms[0]); + _gnutls_mpi_release(¶ms[1]); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + asn1_delete_structure(spk); + + return 0; + +} + +/* reads DSA's Y + * from the certificate + * params[3] + */ +static int _read_dsa_pubkey(opaque * der, int dersize, MPI * params) +{ + opaque str[MAX_PARAMETER_SIZE]; + int result; + node_asn *spk; + + if ( (result=asn1_create_structure + (_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey", &spk, + "dsa_public_key")) != ASN_OK) { + gnutls_assert(); + return GNUTLS_E_ASN1_ERROR; + } + + result = asn1_get_der(spk, der, dersize); + + if (result != ASN_OK) { + gnutls_assert(); + asn1_delete_structure(spk); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + /* Read p */ + + if ( (result=_gnutls_x509_read_int( spk, "dsa_public_key", str, sizeof(str)-1, ¶ms[3])) < 0) { + gnutls_assert(); + asn1_delete_structure(spk); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + asn1_delete_structure(spk); + + return 0; + +} + + +/* Extracts DSA and RSA parameters from a certificate. + */ +static +int _gnutls_extract_x509_cert_mpi_params( const char* ALGO_OID, gnutls_cert * gCert, + node_asn* c2, char* tmpstr, int tmpstr_size) { +int len, result; + + if (strcmp( ALGO_OID, "1 2 840 113549 1 1 1") == 0) { /* pkix-1 1 - RSA */ + /* params[0] is the modulus, + * params[1] is the exponent + */ + gCert->subject_pk_algorithm = GNUTLS_PK_RSA; + + len = tmpstr_size - 1; + result = + asn1_read_value + (c2, "certificate2.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", + tmpstr, &len); + + if (result != ASN_OK) { + gnutls_assert(); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + if ((sizeof(gCert->params) / sizeof(MPI)) < RSA_PARAMS) { + gnutls_assert(); + /* internal error. Increase the MPIs in params */ + return GNUTLS_E_INTERNAL; + } + + if ((result = + _read_rsa_params(tmpstr, len / 8, gCert->params)) < 0) { + gnutls_assert(); + return result; + } + + return 0; + } + + if (strcmp( ALGO_OID, "1 2 840 10040 4 1") == 0) { /* pkix-1 1 - DSA */ + /* params[0] is p, + * params[1] is q, + * params[2] is q, + * params[3] is pub. + */ + gCert->subject_pk_algorithm = GNUTLS_PK_DSA; + + len = tmpstr_size - 1; + result = + asn1_read_value + (c2, "certificate2.tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", + tmpstr, &len); + + if (result != ASN_OK) { + gnutls_assert(); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + if ((sizeof(gCert->params) / sizeof(MPI)) < DSA_PARAMS) { + gnutls_assert(); + /* internal error. Increase the MPIs in params */ + return GNUTLS_E_INTERNAL; + } + + if ((result = + _read_dsa_pubkey(tmpstr, len / 8, gCert->params)) < 0) { + gnutls_assert(); + return result; + } + + /* Now read the parameters + */ + len = tmpstr_size - 1; + result = + asn1_read_value + (c2, "certificate2.tbsCertificate.subjectPublicKeyInfo.algorithm.parameters", + tmpstr, &len); + + if (result != ASN_OK) { + gnutls_assert(); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + if ((result = + _read_dsa_params(tmpstr, len, gCert->params)) < 0) { + gnutls_assert(); + return result; + } + + return 0; + } + + + + /* other types like DH + * currently not supported + */ + gnutls_assert(); + + _gnutls_log("CERT: ALGORITHM: %s\n", ALGO_OID); + + gCert->subject_pk_algorithm = GNUTLS_PK_UNKNOWN; + + return GNUTLS_E_INVALID_PARAMETERS; +} + + + +#define X509_SIG_SIZE 1024 + +/* This function will convert a der certificate, to a format + * (structure) that gnutls can understand and use. Actually the + * important thing on this function is that it extracts the + * certificate's (public key) parameters. + */ +int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert) +{ + int result; + node_asn *c2; + opaque str[MAX_X509_CERT_SIZE]; + int len = sizeof(str); + + memset(gCert, 0, sizeof(gnutls_cert)); + + gCert->valid = 1; + gCert->cert_type = GNUTLS_CRT_X509; + + if (gnutls_set_datum(&gCert->raw, derCert.data, derCert.size) < 0) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + if (asn1_create_structure + (_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2, + "certificate2") + != ASN_OK) { + gnutls_assert(); + gnutls_free_datum( &gCert->raw); + return GNUTLS_E_ASN1_ERROR; + } + + result = asn1_get_der(c2, derCert.data, derCert.size); + if (result != ASN_OK) { + /* couldn't decode DER */ + + _gnutls_log("CERT: Decoding error %d\n", result); + + gnutls_assert(); + asn1_delete_structure(c2); + gnutls_free_datum( &gCert->raw); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + len = sizeof(str) - 1; + result = + asn1_read_value + (c2, + "certificate2.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm", + str, &len); + + if (result != ASN_OK) { + gnutls_assert(); + asn1_delete_structure(c2); + gnutls_free_datum( &gCert->raw); + return GNUTLS_E_ASN1_PARSING_ERROR; + } + + if ( (result=_gnutls_extract_x509_cert_mpi_params( str, gCert, c2, str, sizeof(str))) < 0) { + gnutls_assert(); + asn1_delete_structure(c2); + gnutls_free_datum( &gCert->raw); + return result; + } + + len = gCert->signature.size = X509_SIG_SIZE; + gCert->signature.data = gnutls_malloc( gCert->signature.size); + if (gCert->signature.data==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + result = + asn1_read_value + (c2, "certificate2.signature", gCert->signature.data, &len); + + if ((len % 8) != 0) { + gnutls_assert(); + asn1_delete_structure(c2); + gnutls_free_datum( &gCert->raw); + gnutls_free_datum( &gCert->signature); + return GNUTLS_E_UNIMPLEMENTED_FEATURE; + } + + len /= 8; /* convert to bytes */ + gCert->signature.size = len; /* put the actual sig size */ + + + gCert->expiration_time = + _gnutls_x509_get_time(c2, "certificate2", "notAfter"); + gCert->activation_time = + _gnutls_x509_get_time(c2, "certificate2", "notBefore"); + gCert->version = _gnutls_x509_get_version(c2, "certificate2"); + + if ((result = + _gnutls_get_ext_type(c2, + "certificate2.tbsCertificate.extensions", + gCert)) < 0) { + gnutls_assert(); + asn1_delete_structure(c2); + gnutls_free_datum( &gCert->raw); + return result; + } + + asn1_delete_structure(c2); + + + gCert->valid = 0; /* if we got until here + * the certificate is valid. + */ + + return 0; + +} + +/* Returns 0 if it's ok to use the KXAlgorithm with this cert + * (using KeyUsage field). + */ +int _gnutls_check_x509_key_usage(const gnutls_cert * cert, + KXAlgorithm alg) +{ + if (_gnutls_map_kx_get_cred(alg) == GNUTLS_CRD_CERTIFICATE) { + switch (alg) { + case GNUTLS_KX_RSA: + if (cert->keyUsage != 0) { + if (! + (cert-> + keyUsage & GNUTLS_X509KEY_KEY_ENCIPHERMENT)) + return + GNUTLS_E_X509_KEY_USAGE_VIOLATION; + else + return 0; + } + return 0; + case GNUTLS_KX_DHE_RSA: + case GNUTLS_KX_DHE_DSS: + if (cert->keyUsage != 0) { + if (! + (cert-> + keyUsage & GNUTLS_X509KEY_DIGITAL_SIGNATURE)) + return + GNUTLS_E_X509_KEY_USAGE_VIOLATION; + else + return 0; + } + return 0; + default: + gnutls_assert(); + return GNUTLS_E_X509_KEY_USAGE_VIOLATION; + } + } + return 0; +} diff --git a/lib/x509_extensions.c b/lib/x509_extensions.c index e411c52f9e..68bf6aba65 100644 --- a/lib/x509_extensions.c +++ b/lib/x509_extensions.c @@ -27,7 +27,7 @@ #include <gnutls_global.h> #include "debug.h" #include <gnutls_str.h> - +#include <gnutls_x509.h> /* Here we only extract the KeyUsage field */ @@ -133,14 +133,14 @@ int main(int argc, char** argv) } /* X509 stuff */ - if (gnutls_certificate_allocate_client_sc( &xcred, 2) < 0) { /* space for 2 certificates */ + if (gnutls_certificate_allocate_client_sc( &xcred) < 0) { /* space for 2 certificates */ fprintf(stderr, "memory error\n"); exit(1); } - gnutls_x509pki_set_trust_file( xcred, CAFILE, CRLFILE); - gnutls_x509pki_set_key_file( xcred, CLICERTFILE1, CLIKEYFILE1); - gnutls_x509pki_set_key_file( xcred, CLICERTFILE2, CLIKEYFILE2); -/* gnutls_certificate_client_callback_callback( xcred, cert_callback); */ + gnutls_certificate_set_x509_trust_file( xcred, CAFILE, CRLFILE); + gnutls_certificate_set_x509_key_file( xcred, CLICERTFILE1, CLIKEYFILE1); + gnutls_certificate_set_x509_key_file( xcred, CLICERTFILE2, CLIKEYFILE2); +/* gnutls_certificate_client_callback_func( xcred, cert_callback); */ /* SRP stuff */ if (gnutls_srp_allocate_client_sc( &cred)<0) { diff --git a/src/common.h b/src/common.h index ebed84572c..28605c0187 100644 --- a/src/common.h +++ b/src/common.h @@ -44,7 +44,7 @@ GNUTLS_KXAlgorithm kx; /* in case of X509 PKI */ cert_list = gnutls_certificate_get_peers( state, &cert_list_size); - status = gnutls_x509pki_verify_peers( state); + status = gnutls_certificate_verify_peers( state); switch( status) { case GNUTLS_CERT_NOT_TRUSTED: diff --git a/src/serv.c b/src/serv.c index 3bbe205546..bfdb19b7ce 100644 --- a/src/serv.c +++ b/src/serv.c @@ -256,22 +256,22 @@ int main(int argc, char **argv) exit(1); } - if (gnutls_certificate_allocate_server_sc(&x509_cred, 2) < 0) { + if (gnutls_certificate_allocate_server_sc(&x509_cred) < 0) { fprintf(stderr, "memory error\n"); exit(1); } - if (gnutls_x509pki_set_trust_file( x509_cred, CAFILE, CRLFILE) < 0) { + if (gnutls_certificate_set_x509_trust_file( x509_cred, CAFILE, CRLFILE) < 0) { fprintf(stderr, "X509 PARSE ERROR\nDid you have ca.pem?\n"); exit(1); } - if (gnutls_x509pki_set_key_file( x509_cred, CERTFILE1, KEYFILE1) < 0) { + if (gnutls_certificate_set_x509_key_file( x509_cred, CERTFILE1, KEYFILE1) < 0) { fprintf(stderr, "X509 PARSE ERROR\nDid you have key.pem and cert.pem?\n"); exit(1); } - if (gnutls_x509pki_set_key_file( x509_cred, CERTFILE2, KEYFILE2) < 0) { + if (gnutls_certificate_set_x509_key_file( x509_cred, CERTFILE2, KEYFILE2) < 0) { fprintf(stderr, "X509 PARSE ERROR\nDid you have key.pem and cert.pem?\n"); exit(1); } |