diff --git a/CHANGES b/CHANGES index fa00300ebe67f06852cbb0323b885269ceee126a..8b033f42bf6671e4b3bbab4e0e5b6a2042e90f91 100644 --- a/CHANGES +++ b/CHANGES @@ -17,9 +17,8 @@ when the X509_STORE_CTX structure is set up) and checks the pathlength. There is a NO_CHAIN_VERIFY compilation option to keep the old behaviour: - this is because when it is finally working it will reject chains with - invalid extensions whereas every previous version of OpenSSL and SSLeay - made no checks at all. + this is because it will reject chains with invalid extensions whereas + every previous version of OpenSSL and SSLeay made no checks at all. Trust code: checks the root CA for the relevant trust settings. Trust settings have an initial value consistent with the verify purpose: e.g. @@ -32,6 +31,10 @@ which should be used for version portability: especially since the verify structure is likely to change more often now. + SSL integration. Add purpose and trust to SSL_CTX and SSL and functions + to set them. If not set then assume SSL clients will verify SSL servers + and vice versa. + Two new options to the verify program: -untrusted allows a set of untrusted certificates to be passed in and -purpose which sets the intended purpose of the certificate. If a purpose is set then the diff --git a/apps/s_client.c b/apps/s_client.c index 60a8728c9bc837d4af966a8261b51a1d71de7458..0afd7907a1fdb8723afc9b6104835e1a62a9448e 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -740,6 +740,7 @@ end: if (ctx != NULL) SSL_CTX_free(ctx); if (cbuf != NULL) { memset(cbuf,0,BUFSIZZ); Free(cbuf); } if (sbuf != NULL) { memset(sbuf,0,BUFSIZZ); Free(sbuf); } + X509_cleanup(); if (bio_c_out != NULL) { BIO_free(bio_c_out); diff --git a/apps/s_server.c b/apps/s_server.c index a33e0ff1477046506bca972a357bd2d948c5e469..7a3a028b6e296e43b897020ca2af2dd705dccad0 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -718,6 +718,7 @@ bad: ret=0; end: if (ctx != NULL) SSL_CTX_free(ctx); + X509_cleanup(); if (bio_s_out != NULL) { BIO_free(bio_s_out); diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 11f462f461946f04042a8c5a1768d7be2435f93b..2668bd19594169d6501e76c35a13f30a5de5b5e9 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -732,9 +732,9 @@ int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); } -void X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) { - ctx->trust = trust; + return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); } /* This function is used to set the X509_STORE_CTX purpose and trust diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h index 822d9c7ea654cfb27828566b883c91de1bb5a89c..3e97df14eecbf4cc6a5327867c81db8be4f5ecc9 100644 --- a/crypto/x509/x509_vfy.h +++ b/crypto/x509/x509_vfy.h @@ -350,7 +350,7 @@ STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); void X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x); void X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk); int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); -void X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, int purpose, int trust); diff --git a/ssl/Makefile.ssl b/ssl/Makefile.ssl index 0eb0b0ccc2dd50c430eefbcb0aca23c2c4132ed4..04ed4b3b814ae60b1868cc48f9460e9e79c149d9 100644 --- a/ssl/Makefile.ssl +++ b/ssl/Makefile.ssl @@ -537,24 +537,26 @@ ssl_asn1.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h ssl_cert.o: ../include/openssl/asn1.h ../include/openssl/bio.h ssl_cert.o: ../include/openssl/blowfish.h ../include/openssl/bn.h ssl_cert.o: ../include/openssl/buffer.h ../include/openssl/cast.h -ssl_cert.o: ../include/openssl/comp.h ../include/openssl/crypto.h -ssl_cert.o: ../include/openssl/des.h ../include/openssl/dh.h -ssl_cert.o: ../include/openssl/dsa.h ../include/openssl/e_os.h -ssl_cert.o: ../include/openssl/e_os.h ../include/openssl/e_os2.h -ssl_cert.o: ../include/openssl/err.h ../include/openssl/evp.h -ssl_cert.o: ../include/openssl/idea.h ../include/openssl/lhash.h -ssl_cert.o: ../include/openssl/md2.h ../include/openssl/md5.h -ssl_cert.o: ../include/openssl/mdc2.h ../include/openssl/objects.h -ssl_cert.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h -ssl_cert.o: ../include/openssl/pem.h ../include/openssl/pem2.h -ssl_cert.o: ../include/openssl/pkcs7.h ../include/openssl/rc2.h -ssl_cert.o: ../include/openssl/rc4.h ../include/openssl/rc5.h -ssl_cert.o: ../include/openssl/ripemd.h ../include/openssl/rsa.h -ssl_cert.o: ../include/openssl/safestack.h ../include/openssl/sha.h -ssl_cert.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h -ssl_cert.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h -ssl_cert.o: ../include/openssl/stack.h ../include/openssl/tls1.h -ssl_cert.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h +ssl_cert.o: ../include/openssl/comp.h ../include/openssl/conf.h +ssl_cert.o: ../include/openssl/crypto.h ../include/openssl/des.h +ssl_cert.o: ../include/openssl/dh.h ../include/openssl/dsa.h +ssl_cert.o: ../include/openssl/e_os.h ../include/openssl/e_os.h +ssl_cert.o: ../include/openssl/e_os2.h ../include/openssl/err.h +ssl_cert.o: ../include/openssl/evp.h ../include/openssl/idea.h +ssl_cert.o: ../include/openssl/lhash.h ../include/openssl/md2.h +ssl_cert.o: ../include/openssl/md5.h ../include/openssl/mdc2.h +ssl_cert.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h +ssl_cert.o: ../include/openssl/opensslv.h ../include/openssl/pem.h +ssl_cert.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h +ssl_cert.o: ../include/openssl/rc2.h ../include/openssl/rc4.h +ssl_cert.o: ../include/openssl/rc5.h ../include/openssl/ripemd.h +ssl_cert.o: ../include/openssl/rsa.h ../include/openssl/safestack.h +ssl_cert.o: ../include/openssl/sha.h ../include/openssl/ssl.h +ssl_cert.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h +ssl_cert.o: ../include/openssl/ssl3.h ../include/openssl/stack.h +ssl_cert.o: ../include/openssl/tls1.h ../include/openssl/x509.h +ssl_cert.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h +ssl_cert.o: ssl_locl.h ssl_ciph.o: ../include/openssl/asn1.h ../include/openssl/bio.h ssl_ciph.o: ../include/openssl/blowfish.h ../include/openssl/bn.h ssl_ciph.o: ../include/openssl/buffer.h ../include/openssl/cast.h @@ -619,24 +621,25 @@ ssl_err2.o: ../include/openssl/x509_vfy.h ssl_lib.o: ../include/openssl/asn1.h ../include/openssl/bio.h ssl_lib.o: ../include/openssl/blowfish.h ../include/openssl/bn.h ssl_lib.o: ../include/openssl/buffer.h ../include/openssl/cast.h -ssl_lib.o: ../include/openssl/comp.h ../include/openssl/crypto.h -ssl_lib.o: ../include/openssl/des.h ../include/openssl/dh.h -ssl_lib.o: ../include/openssl/dsa.h ../include/openssl/e_os.h -ssl_lib.o: ../include/openssl/e_os2.h ../include/openssl/err.h -ssl_lib.o: ../include/openssl/evp.h ../include/openssl/idea.h -ssl_lib.o: ../include/openssl/lhash.h ../include/openssl/md2.h -ssl_lib.o: ../include/openssl/md5.h ../include/openssl/mdc2.h -ssl_lib.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h -ssl_lib.o: ../include/openssl/opensslv.h ../include/openssl/pem.h -ssl_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h -ssl_lib.o: ../include/openssl/rc2.h ../include/openssl/rc4.h -ssl_lib.o: ../include/openssl/rc5.h ../include/openssl/ripemd.h -ssl_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h -ssl_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h -ssl_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h -ssl_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h -ssl_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h -ssl_lib.o: ../include/openssl/x509_vfy.h ssl_locl.h +ssl_lib.o: ../include/openssl/comp.h ../include/openssl/conf.h +ssl_lib.o: ../include/openssl/crypto.h ../include/openssl/des.h +ssl_lib.o: ../include/openssl/dh.h ../include/openssl/dsa.h +ssl_lib.o: ../include/openssl/e_os.h ../include/openssl/e_os2.h +ssl_lib.o: ../include/openssl/err.h ../include/openssl/evp.h +ssl_lib.o: ../include/openssl/idea.h ../include/openssl/lhash.h +ssl_lib.o: ../include/openssl/md2.h ../include/openssl/md5.h +ssl_lib.o: ../include/openssl/mdc2.h ../include/openssl/objects.h +ssl_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h +ssl_lib.o: ../include/openssl/pem.h ../include/openssl/pem2.h +ssl_lib.o: ../include/openssl/pkcs7.h ../include/openssl/rc2.h +ssl_lib.o: ../include/openssl/rc4.h ../include/openssl/rc5.h +ssl_lib.o: ../include/openssl/ripemd.h ../include/openssl/rsa.h +ssl_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h +ssl_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h +ssl_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h +ssl_lib.o: ../include/openssl/stack.h ../include/openssl/tls1.h +ssl_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h +ssl_lib.o: ../include/openssl/x509v3.h ssl_locl.h ssl_rsa.o: ../include/openssl/asn1.h ../include/openssl/bio.h ssl_rsa.o: ../include/openssl/blowfish.h ../include/openssl/bn.h ssl_rsa.o: ../include/openssl/buffer.h ../include/openssl/cast.h diff --git a/ssl/ssl.h b/ssl/ssl.h index 1b39f0d2ea51ca09ac4f1608df94067979e56ebd..96c5a93aecacb62968ee5160f528e7337a12d957 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -1009,6 +1009,12 @@ int SSL_CTX_set_session_id_context(SSL_CTX *ctx,const unsigned char *sid_ctx, SSL * SSL_new(SSL_CTX *ctx); int SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx, unsigned int sid_ctx_len); + +int SSL_CTX_set_purpose(SSL_CTX *s, int purpose); +int SSL_set_purpose(SSL *s, int purpose); +int SSL_CTX_set_trust(SSL_CTX *s, int trust); +int SSL_set_trust(SSL *s, int trust); + void SSL_free(SSL *ssl); int SSL_accept(SSL *ssl); int SSL_connect(SSL *ssl); @@ -1235,8 +1241,10 @@ int SSL_COMP_add_compression_method(int id,char *cm); #define SSL_F_SSL_CREATE_CIPHER_LIST 166 #define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168 #define SSL_F_SSL_CTX_NEW 169 +#define SSL_F_SSL_CTX_SET_PURPOSE 226 #define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219 #define SSL_F_SSL_CTX_SET_SSL_VERSION 170 +#define SSL_F_SSL_CTX_SET_TRUST 229 #define SSL_F_SSL_CTX_USE_CERTIFICATE 171 #define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 #define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE 220 @@ -1264,9 +1272,11 @@ int SSL_COMP_add_compression_method(int id,char *cm); #define SSL_F_SSL_SET_CERT 191 #define SSL_F_SSL_SET_FD 192 #define SSL_F_SSL_SET_PKEY 193 +#define SSL_F_SSL_SET_PURPOSE 227 #define SSL_F_SSL_SET_RFD 194 #define SSL_F_SSL_SET_SESSION 195 #define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 +#define SSL_F_SSL_SET_TRUST 228 #define SSL_F_SSL_SET_WFD 196 #define SSL_F_SSL_SHUTDOWN 224 #define SSL_F_SSL_UNDEFINED_FUNCTION 197 @@ -1348,6 +1358,8 @@ int SSL_COMP_add_compression_method(int id,char *cm); #define SSL_R_HTTP_REQUEST 156 #define SSL_R_INTERNAL_ERROR 157 #define SSL_R_INVALID_CHALLENGE_LENGTH 158 +#define SSL_R_INVALID_PURPOSE 278 +#define SSL_R_INVALID_TRUST 279 #define SSL_R_LENGTH_MISMATCH 159 #define SSL_R_LENGTH_TOO_SHORT 160 #define SSL_R_LIBRARY_BUG 274 diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index a695d042cf2e9f8e15ced5b840a4901fe69e905e..3eda14aea97459de3c631e1fcf1ff2ca13072731 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -124,6 +124,7 @@ #include #include #include +#include #include "ssl_locl.h" int SSL_get_ex_data_X509_STORE_CTX_idx(void) @@ -432,6 +433,15 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk) X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s)); X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(), (char *)s); + /* We need to set the verify purpose. The purpose can be determined by + * the context: if its a server it will verify SSL client certificates + * or vice versa. + */ + + if(s->server) i = X509_PURPOSE_SSL_CLIENT; + else i = X509_PURPOSE_SSL_SERVER; + + X509_STORE_CTX_purpose_inherit(&ctx, i, s->purpose, s->trust); if (s->ctx->app_verify_callback != NULL) i=s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */ @@ -542,7 +552,7 @@ int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x) return(add_client_CA(&(ctx->client_CA),x)); } -static int name_cmp(X509_NAME **a,X509_NAME **b) +static int xname_cmp(X509_NAME **a,X509_NAME **b) { return(X509_NAME_cmp(*a,*b)); } @@ -564,7 +574,7 @@ STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) STACK_OF(X509_NAME) *ret,*sk; ret=sk_X509_NAME_new(NULL); - sk=sk_X509_NAME_new(name_cmp); + sk=sk_X509_NAME_new(xname_cmp); in=BIO_new(BIO_s_file_internal()); @@ -625,7 +635,7 @@ int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, int ret=1; int (*oldcmp)(X509_NAME **a, X509_NAME **b); - oldcmp=sk_X509_NAME_set_cmp_func(stack,name_cmp); + oldcmp=sk_X509_NAME_set_cmp_func(stack,xname_cmp); in=BIO_new(BIO_s_file_internal()); diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 3ddc805b537067cb2445b0210486900972626882..7c611650f33591e82908249227a696c2dc0cd80a 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -140,8 +140,10 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_PACK(0,SSL_F_SSL_CREATE_CIPHER_LIST,0), "SSL_CREATE_CIPHER_LIST"}, {ERR_PACK(0,SSL_F_SSL_CTX_CHECK_PRIVATE_KEY,0), "SSL_CTX_check_private_key"}, {ERR_PACK(0,SSL_F_SSL_CTX_NEW,0), "SSL_CTX_new"}, +{ERR_PACK(0,SSL_F_SSL_CTX_SET_PURPOSE,0), "SSL_CTX_set_purpose"}, {ERR_PACK(0,SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT,0), "SSL_CTX_set_session_id_context"}, {ERR_PACK(0,SSL_F_SSL_CTX_SET_SSL_VERSION,0), "SSL_CTX_set_ssl_version"}, +{ERR_PACK(0,SSL_F_SSL_CTX_SET_TRUST,0), "SSL_CTX_set_trust"}, {ERR_PACK(0,SSL_F_SSL_CTX_USE_CERTIFICATE,0), "SSL_CTX_use_certificate"}, {ERR_PACK(0,SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1,0), "SSL_CTX_use_certificate_ASN1"}, {ERR_PACK(0,SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,0), "SSL_CTX_use_certificate_chain_file"}, @@ -169,9 +171,11 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_PACK(0,SSL_F_SSL_SET_CERT,0), "SSL_SET_CERT"}, {ERR_PACK(0,SSL_F_SSL_SET_FD,0), "SSL_set_fd"}, {ERR_PACK(0,SSL_F_SSL_SET_PKEY,0), "SSL_SET_PKEY"}, +{ERR_PACK(0,SSL_F_SSL_SET_PURPOSE,0), "SSL_set_purpose"}, {ERR_PACK(0,SSL_F_SSL_SET_RFD,0), "SSL_set_rfd"}, {ERR_PACK(0,SSL_F_SSL_SET_SESSION,0), "SSL_set_session"}, {ERR_PACK(0,SSL_F_SSL_SET_SESSION_ID_CONTEXT,0), "SSL_set_session_id_context"}, +{ERR_PACK(0,SSL_F_SSL_SET_TRUST,0), "SSL_set_trust"}, {ERR_PACK(0,SSL_F_SSL_SET_WFD,0), "SSL_set_wfd"}, {ERR_PACK(0,SSL_F_SSL_SHUTDOWN,0), "SSL_shutdown"}, {ERR_PACK(0,SSL_F_SSL_UNDEFINED_FUNCTION,0), "SSL_UNDEFINED_FUNCTION"}, @@ -256,6 +260,8 @@ static ERR_STRING_DATA SSL_str_reasons[]= {SSL_R_HTTP_REQUEST ,"http request"}, {SSL_R_INTERNAL_ERROR ,"internal error"}, {SSL_R_INVALID_CHALLENGE_LENGTH ,"invalid challenge length"}, +{SSL_R_INVALID_PURPOSE ,"invalid purpose"}, +{SSL_R_INVALID_TRUST ,"invalid trust"}, {SSL_R_LENGTH_MISMATCH ,"length mismatch"}, {SSL_R_LENGTH_TOO_SHORT ,"length too short"}, {SSL_R_LIBRARY_BUG ,"library bug"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 9dd6860d96a1a8cec4f0fedc9f574cfd3eb60e8c..3bd8d158c90e2c3a7245735d1a6082914a840dbb 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -61,6 +61,7 @@ #include #include #include +#include #include "ssl_locl.h" char *SSL_version_str=OPENSSL_VERSION_TEXT; @@ -264,6 +265,46 @@ int SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx, return 1; } +int SSL_CTX_set_purpose(SSL_CTX *s, int purpose) +{ + if(X509_PURPOSE_get_by_id(purpose) == -1) { + SSLerr(SSL_F_SSL_CTX_SET_PURPOSE, SSL_R_INVALID_PURPOSE); + return 0; + } + s->purpose = purpose; + return 1; +} + +int SSL_set_purpose(SSL *s, int purpose) +{ + if(X509_PURPOSE_get_by_id(purpose) == -1) { + SSLerr(SSL_F_SSL_SET_PURPOSE, SSL_R_INVALID_PURPOSE); + return 0; + } + s->purpose = purpose; + return 1; +} + +int SSL_CTX_set_trust(SSL_CTX *s, int trust) +{ + if(X509_TRUST_get_by_id(trust) == -1) { + SSLerr(SSL_F_SSL_CTX_SET_TRUST, SSL_R_INVALID_TRUST); + return 0; + } + s->trust = trust; + return 1; +} + +int SSL_set_trust(SSL *s, int trust) +{ + if(X509_TRUST_get_by_id(trust) == -1) { + SSLerr(SSL_F_SSL_SET_TRUST, SSL_R_INVALID_TRUST); + return 0; + } + s->trust = trust; + return 1; +} + void SSL_free(SSL *s) { int i; @@ -1079,6 +1120,12 @@ SSL_CTX *SSL_CTX_new(SSL_METHOD *meth) ret->extra_certs=NULL; ret->comp_methods=SSL_COMP_get_compression_methods(); + /* Initialise X509 tables: otherwise some certificate operations + * wont work. This is a non op if called more than once. + */ + + X509_init(); + return(ret); err: SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE); diff --git a/util/ssleay.num b/util/ssleay.num index 8121738bd674ffdfadf4fbc6444a541abe0de6d6..ee95837563ae09f43fcbac454e4c5269637ae9ca 100755 --- a/util/ssleay.num +++ b/util/ssleay.num @@ -215,3 +215,7 @@ SSL_CTX_set_cert_verify_callback 232 sk_SSL_COMP_sort 233 sk_SSL_CIPHER_sort 234 SSL_CTX_set_default_passwd_cb_userdata 235 +SSL_set_purpose 236 +SSL_CTX_set_trust 237 +SSL_CTX_set_purpose 238 +SSL_set_trust 239