From: Nikos Mavrogiannopoulos Date: Tue, 24 Jul 2001 20:02:06 +0000 (+0000) Subject: gnutls now checks the certificate's CN to see if it matches the X-Git-Tag: gnutls_0_1_9~25 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4e29b8a8741f33767d0792930d9f0a8d9bc7741a;p=thirdparty%2Fgnutls.git gnutls now checks the certificate's CN to see if it matches the peer's name. --- diff --git a/doc/TODO b/doc/TODO index 6eaf43246d..a782aa31df 100644 --- a/doc/TODO +++ b/doc/TODO @@ -4,4 +4,3 @@ * Tools for processing/generating certificates * Add certificate extensions support (x509v3) * Documentation (of existing functions + Manual) -* fix get_Name_type() to return the country too diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c index c36e24247f..1a410b4c6e 100644 --- a/lib/auth_rsa.c +++ b/lib/auth_rsa.c @@ -455,7 +455,7 @@ int proc_rsa_certificate(GNUTLS_KEY key, opaque * data, int data_size) ret = GNUTLS_CERT_NOT_TRUSTED; ret = gnutls_verify_certificate( peer_certificate_list, peer_certificate_list_size, - cred->ca_list, cred->ncas, NULL, 0); + cred->ca_list, cred->ncas, NULL, 0, key->x509_cn); info->peer_certificate_status = ret; diff --git a/lib/cert_verify.c b/lib/cert_verify.c index ead27f35e0..682bd629cc 100644 --- a/lib/cert_verify.c +++ b/lib/cert_verify.c @@ -318,9 +318,9 @@ int gnutls_verify_certificate2(gnutls_cert * cert, gnutls_cert * trusted_cas, in return GNUTLS_CERT_TRUSTED; } -int gnutls_verify_certificate(gnutls_cert * certificate_list, +int gnutls_verify_certificate( gnutls_cert * certificate_list, int clist_size, gnutls_cert * trusted_cas, int tcas_size, void *CRLs, - int crls_size) + int crls_size, char* cn) { int i = 0; int expired = 0; @@ -346,11 +346,18 @@ int gnutls_verify_certificate(gnutls_cert * certificate_list, } ret = gnutls_verify_certificate2(&certificate_list[i], trusted_cas, tcas_size, CRLs, crls_size); + + if (ret==GNUTLS_CERT_EXPIRED) { + expired = 1; + } else + if (ret != GNUTLS_CERT_TRUSTED) + return ret; - if (ret != GNUTLS_CERT_TRUSTED) - return ret; + if ( strcmp( certificate_list[0].cert_info.common_name, cn) != 0) + return GNUTLS_CERT_WRONG_CN; if (expired != 0) return GNUTLS_CERT_EXPIRED; + return GNUTLS_CERT_TRUSTED; } diff --git a/lib/cert_verify.h b/lib/cert_verify.h index 99c88e3251..878bda875a 100644 --- a/lib/cert_verify.h +++ b/lib/cert_verify.h @@ -1,5 +1,5 @@ int gnutls_verify_certificate(gnutls_cert * certificate_list, int clist_size, gnutls_cert * trusted_cas, int tcas_size, void *CRLs, - int crls_size); + int crls_size, char* cn); time_t _gnutls_utcTime2gtime(char *ttime); time_t _gnutls_generalTime2gtime(char *ttime); diff --git a/lib/gnutls.h.in b/lib/gnutls.h.in index 30c0e45623..54353c4be7 100644 --- a/lib/gnutls.h.in +++ b/lib/gnutls.h.in @@ -138,6 +138,12 @@ const void* gnutls_get_auth_info( GNUTLS_STATE); const char* gnutls_ext_get_dnsname( GNUTLS_STATE); int gnutls_ext_set_dnsname( GNUTLS_STATE, const char* dnsname); +/* This will set the Common Name field in case of X509PKI + * authentication. This will be used while verifying the + * certificate + */ +int gnutls_x509_set_cn( GNUTLS_STATE, const char* cn); + /* Credential structures for SRP - used in gnutls_set_cred(); */ @@ -179,7 +185,7 @@ typedef struct { char username[256]; } SRP_SERVER_AUTH_INFO; -typedef enum CertificateStatus { GNUTLS_CERT_TRUSTED=1, GNUTLS_CERT_NOT_TRUSTED, GNUTLS_CERT_EXPIRED, GNUTLS_CERT_INVALID } CertificateStatus; +typedef enum CertificateStatus { GNUTLS_CERT_TRUSTED=1, GNUTLS_CERT_NOT_TRUSTED, GNUTLS_CERT_EXPIRED, GNUTLS_CERT_WRONG_CN, GNUTLS_CERT_INVALID } CertificateStatus; typedef struct { char common_name[256]; diff --git a/lib/gnutls_auth.c b/lib/gnutls_auth.c index e556975898..168b8714aa 100644 --- a/lib/gnutls_auth.c +++ b/lib/gnutls_auth.c @@ -177,3 +177,21 @@ const void *_gnutls_get_cred( GNUTLS_KEY key, CredType type, int *err) { const void* gnutls_get_auth_info( GNUTLS_STATE state) { return state->gnutls_key->auth_info; } + +/** + * gnutls_x509_set_cn - Used to set the CN for X509 authentication + * @state: is a &GNUTLS_STATE structure. + * @cn: is a null terminated string that contains the peer's CN. + * + * This function is to be used by clients that want to verify + * also the peer's Common Name (ie. the certificate may be verified, + * but it may have been issued for someone else). + **/ +int gnutls_x509_set_cn( GNUTLS_STATE state, const char* cn) { + + if (strlen( cn) >= X509_CN_SIZE) return GNUTLS_E_MEMORY_ERROR; + + strcpy( state->gnutls_key->x509_cn, cn); + + return 0; +} diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c index 81f683fdc4..91eafc9db4 100644 --- a/lib/gnutls_cert.c +++ b/lib/gnutls_cert.c @@ -221,26 +221,11 @@ gnutls_datum tmp; res->ca_list = NULL; -{FILE* fd; -fd = fopen("/tmp/aaa1", "w"); -fwrite( ptr, siz, 1, fd); -fclose(fd); - -} - - do { siz2 = _gnutls_fbase64_decode(ptr, siz, &b64); siz-=siz2; /* FIXME: this is not enough */ -{FILE* fd; -fd = fopen("/tmp/test1", "w"); -fwrite( b64, siz2, 1, fd); -fclose(fd); - -} - if (siz2 < 0) { gnutls_assert(); gnutls_free(b64); @@ -523,6 +508,7 @@ void _gnutls_int2str(int k, char* data) { * ASN.1 structure. (Taken from Fabio's samples!) * --nmav */ +#warning "Fix COUNTRY/EMAIL" static int _get_Name_type( node_asn *rasn, char *root, gnutls_DN * dn) { int k, k2, result, len; diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h index f660327d3c..5e015229aa 100644 --- a/lib/gnutls_cert.h +++ b/lib/gnutls_cert.h @@ -4,12 +4,12 @@ #include typedef struct { - char common_name[256]; - char country[3]; - char organization[256]; - char organizational_unit_name[256]; - char locality_name[256]; - char state_or_province_name[256]; + char common_name[X509_CN_SIZE]; + char country[X509_C_SIZE]; + char organization[X509_O_SIZE]; + char organizational_unit_name[X509_OU_SIZE]; + char locality_name[X509_L_SIZE]; + char state_or_province_name[X509_S_SIZE]; } gnutls_DN; diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 7fa6719463..0cbe811de3 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -61,6 +61,14 @@ #define HEADER_SIZE 5 #define MAX_RECV_SIZE 18432+HEADER_SIZE /* 2^14+2048+HEADER_SIZE */ +/* X509 */ +#define X509_CN_SIZE 256 +#define X509_C_SIZE 3 +#define X509_O_SIZE 256 +#define X509_OU_SIZE 256 +#define X509_L_SIZE 256 +#define X509_S_SIZE 256 + #ifdef USE_DMALLOC # include #endif @@ -99,7 +107,7 @@ typedef enum AlertDescription { GNUTLS_CLOSE_NOTIFY, GNUTLS_UNEXPECTED_MESSAGE=1 GNUTLS_INSUFFICIENT_SECURITY, GNUTLS_INTERNAL_ERROR=80, GNUTLS_USER_CANCELED=90, GNUTLS_NO_RENEGOTIATION=100 } AlertDescription; -typedef enum CertificateStatus { GNUTLS_CERT_TRUSTED=1, GNUTLS_CERT_NOT_TRUSTED, GNUTLS_CERT_EXPIRED, GNUTLS_CERT_INVALID } CertificateStatus; +typedef enum CertificateStatus { GNUTLS_CERT_TRUSTED=1, GNUTLS_CERT_NOT_TRUSTED, GNUTLS_CERT_EXPIRED, GNUTLS_CERT_WRONG_CN, GNUTLS_CERT_INVALID } CertificateStatus; typedef enum HandshakeType { GNUTLS_HELLO_REQUEST, GNUTLS_CLIENT_HELLO, GNUTLS_SERVER_HELLO, GNUTLS_CERTIFICATE=11, GNUTLS_SERVER_KEY_EXCHANGE, @@ -188,6 +196,8 @@ typedef struct { opaque client_random[TLS_RANDOM_SIZE]; ProtocolVersion version; + opaque x509_cn[X509_CN_SIZE]; + AUTH_CRED* cred; /* used to specify keys/certificates etc */ } GNUTLS_KEY_A; typedef GNUTLS_KEY_A* GNUTLS_KEY; diff --git a/lib/gnutls_sig_check.c b/lib/gnutls_sig_check.c index 53bdb0de93..6ad8780213 100644 --- a/lib/gnutls_sig_check.c +++ b/lib/gnutls_sig_check.c @@ -58,7 +58,12 @@ int result, len; asn1_delete_structure(c2); return NULL; } - +{ +FILE* fd; +fd = fopen("/tmp/der", "w"); +fwrite( str, len, 1, fd); +fclose(fd); +} asn1_delete_structure(c2); ret = gnutls_malloc(sizeof(gnutls_cert)); diff --git a/src/cli.c b/src/cli.c index aaf1b7bf4a..c7bd226841 100644 --- a/src/cli.c +++ b/src/cli.c @@ -75,6 +75,9 @@ const X509PKI_CLIENT_AUTH_INFO *x509_info; case GNUTLS_CERT_TRUSTED: printf("- Peer's X509 Certificate was verified\n"); break; + case GNUTLS_CERT_WRONG_CN: + printf("- Peer's X509 Certificate was verified but it does not match the server's name\n"); + break; case GNUTLS_CERT_INVALID: default: printf("- Peer's X509 Certificate was invalid\n"); @@ -172,14 +175,15 @@ int main(int argc, char** argv) gnutls_set_cipher_priority( state, GNUTLS_3DES_CBC, GNUTLS_ARCFOUR, GNUTLS_RIJNDAEL_CBC, 0); gnutls_set_compression_priority( state, GNUTLS_ZLIB, GNUTLS_NULL_COMPRESSION, 0); gnutls_set_kx_priority( state, GNUTLS_KX_RSA, GNUTLS_KX_SRP, GNUTLS_KX_DH_ANON, 0); - gnutls_set_cred( state, GNUTLS_ANON, NULL); + gnutls_set_mac_priority( state, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0); + gnutls_set_cred( state, GNUTLS_ANON, NULL); gnutls_set_cred( state, GNUTLS_SRP, cred); - gnutls_set_cred( state, GNUTLS_X509PKI, xcred); - gnutls_ext_set_dnsname( state, "hello.server.org"); - - gnutls_set_mac_priority( state, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0); + + gnutls_ext_set_dnsname( state, "localhost"); + gnutls_x509_set_cn( state, "localhost"); + ret = gnutls_handshake(sd, state); if (ret < 0) {