aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/x509
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>1999-11-27 19:43:10 +0000
committerDr. Stephen Henson <steve@openssl.org>1999-11-27 19:43:10 +0000
commit51630a37069a0792f2d6ad6ce33e9c5cca27b69c (patch)
tree295ee6e11fede84a1ac1cf5404b1c3edfe2e7ba8 /crypto/x509
parent74ecf9e2bbff8bb85b8da313b2ea44df487ef550 (diff)
downloadopenssl-51630a37069a0792f2d6ad6ce33e9c5cca27b69c.tar.gz
Add trust setting support to the verify code. It now checks the
trust settings of the root CA. After a few fixes it seems to work OK. Still need to add support to SSL and S/MIME code though.
Diffstat (limited to 'crypto/x509')
-rw-r--r--crypto/x509/x509.h2
-rw-r--r--crypto/x509/x509_err.c4
-rw-r--r--crypto/x509/x509_txt.c4
-rw-r--r--crypto/x509/x509_vfy.c52
-rw-r--r--crypto/x509/x509_vfy.h5
5 files changed, 63 insertions, 4 deletions
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
index 227bbaf1ca..534c3d69f7 100644
--- a/crypto/x509/x509.h
+++ b/crypto/x509/x509.h
@@ -1098,6 +1098,7 @@ int X509_TRUST_get_trust(X509_TRUST *xp);
#define X509_F_X509_REQ_PRINT 121
#define X509_F_X509_REQ_PRINT_FP 122
#define X509_F_X509_REQ_TO_X509 123
+#define X509_F_X509_SET_PURPOSE_AND_TRUST 134
#define X509_F_X509_STORE_ADD_CERT 124
#define X509_F_X509_STORE_ADD_CRL 125
#define X509_F_X509_TO_X509_REQ 126
@@ -1122,6 +1123,7 @@ int X509_TRUST_get_trust(X509_TRUST *xp);
#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108
#define X509_R_UNKNOWN_KEY_TYPE 117
#define X509_R_UNKNOWN_NID 109
+#define X509_R_UNKNOWN_TRUST_ID 120
#define X509_R_UNSUPPORTED_ALGORITHM 111
#define X509_R_WRONG_LOOKUP_TYPE 112
diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c
index c185bc02f8..acaa99ffae 100644
--- a/crypto/x509/x509_err.c
+++ b/crypto/x509/x509_err.c
@@ -91,10 +91,11 @@ static ERR_STRING_DATA X509_str_functs[]=
{ERR_PACK(0,X509_F_X509_REQ_PRINT,0), "X509_REQ_print"},
{ERR_PACK(0,X509_F_X509_REQ_PRINT_FP,0), "X509_REQ_print_fp"},
{ERR_PACK(0,X509_F_X509_REQ_TO_X509,0), "X509_REQ_to_X509"},
+{ERR_PACK(0,X509_F_X509_SET_PURPOSE_AND_TRUST,0), "X509_set_purpose_and_trust"},
{ERR_PACK(0,X509_F_X509_STORE_ADD_CERT,0), "X509_STORE_add_cert"},
{ERR_PACK(0,X509_F_X509_STORE_ADD_CRL,0), "X509_STORE_add_crl"},
{ERR_PACK(0,X509_F_X509_TO_X509_REQ,0), "X509_to_X509_REQ"},
-{ERR_PACK(0,X509_F_X509_TRUST_ADD,0), "X509_TRUST_ADD"},
+{ERR_PACK(0,X509_F_X509_TRUST_ADD,0), "X509_TRUST_add"},
{ERR_PACK(0,X509_F_X509_VERIFY_CERT,0), "X509_verify_cert"},
{0,NULL}
};
@@ -118,6 +119,7 @@ static ERR_STRING_DATA X509_str_reasons[]=
{X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY ,"unable to get certs public key"},
{X509_R_UNKNOWN_KEY_TYPE ,"unknown key type"},
{X509_R_UNKNOWN_NID ,"unknown nid"},
+{X509_R_UNKNOWN_TRUST_ID ,"unknown trust id"},
{X509_R_UNSUPPORTED_ALGORITHM ,"unsupported algorithm"},
{X509_R_WRONG_LOOKUP_TYPE ,"wrong lookup type"},
{0,NULL}
diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c
index b6f61c5e57..209cf53191 100644
--- a/crypto/x509/x509_txt.c
+++ b/crypto/x509/x509_txt.c
@@ -126,6 +126,10 @@ const char *X509_verify_cert_error_string(long n)
return ("path length constraint exceeded");
case X509_V_ERR_INVALID_PURPOSE:
return ("unsupported certificate purpose");
+ case X509_V_ERR_CERT_UNTRUSTED:
+ return ("certificate not trusted");
+ case X509_V_ERR_CERT_REJECTED:
+ return ("certificate rejected");
case X509_V_ERR_APPLICATION_VERIFICATION:
return("application verification failure");
default:
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 3d1b38a019..75ab96e506 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -72,6 +72,7 @@
static int null_callback(int ok,X509_STORE_CTX *e);
static int check_chain_purpose(X509_STORE_CTX *ctx);
+static int check_trust(X509_STORE_CTX *ctx);
static int internal_verify(X509_STORE_CTX *ctx);
const char *X509_version="X.509" OPENSSL_VERSION_PTEXT;
@@ -297,6 +298,12 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
if(!ok) goto end;
+ /* The chain extensions are OK: check trust */
+
+ if(ctx->trust_purpose > 0) ok = check_trust(ctx);
+
+ if(!ok) goto end;
+
/* We may as well copy down any DSA parameters that are required */
X509_get_pubkey_parameters(NULL,ctx->chain);
@@ -356,6 +363,30 @@ static int check_chain_purpose(X509_STORE_CTX *ctx)
#endif
}
+static int check_trust(X509_STORE_CTX *ctx)
+{
+#ifdef NO_CHAIN_VERIFY
+ return 1;
+#else
+ int i, ok;
+ X509 *x;
+ int (*cb)();
+ cb=ctx->ctx->verify_cb;
+ if (cb == NULL) cb=null_callback;
+/* For now just check the last certificate in the chain */
+ i = sk_X509_num(ctx->chain) - 1;
+ x = sk_X509_value(ctx->chain, i);
+ ok = X509_check_trust(x, ctx->trust_purpose, 0);
+ if(ok == X509_TRUST_TRUSTED) return 1;
+ ctx->error_depth = sk_X509_num(ctx->chain) - 1;
+ ctx->current_cert = x;
+ if(ok == X509_TRUST_REJECTED) ctx->error = X509_V_ERR_CERT_REJECTED;
+ else ctx->error = X509_V_ERR_CERT_UNTRUSTED;
+ ok = cb(0, ctx);
+ return(ok);
+#endif
+}
+
static int internal_verify(X509_STORE_CTX *ctx)
{
int i,ok=0,n;
@@ -696,9 +727,10 @@ void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
ctx->untrusted=sk;
}
-void X509_STORE_CTX_chain_purpose(X509_STORE_CTX *ctx, int purpose)
+int X509_STORE_CTX_chain_purpose(X509_STORE_CTX *ctx, int purpose)
{
- ctx->chain_purpose = purpose;
+ return X509_set_purpose_and_trust(purpose,
+ &ctx->chain_purpose, &ctx->trust_purpose);
}
void X509_STORE_CTX_trust_purpose(X509_STORE_CTX *ctx, int purpose)
@@ -706,6 +738,22 @@ void X509_STORE_CTX_trust_purpose(X509_STORE_CTX *ctx, int purpose)
ctx->trust_purpose = purpose;
}
+int X509_set_purpose_and_trust(int id, int *purp, int *trust)
+{
+ X509_PURPOSE *ptmp;
+ int idx;
+ idx = X509_PURPOSE_get_by_id(id);
+ if(idx == -1) {
+ X509err(X509_F_X509_SET_PURPOSE_AND_TRUST,
+ X509_R_UNKNOWN_TRUST_ID);
+ return 0;
+ }
+ ptmp = X509_PURPOSE_iget(idx);
+ if(purp) *purp = id;
+ if(trust) *trust = ptmp->trust_id;
+ return 1;
+}
+
IMPLEMENT_STACK_OF(X509)
IMPLEMENT_ASN1_SET_OF(X509)
diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h
index 47c0b4028c..5e197040fb 100644
--- a/crypto/x509/x509_vfy.h
+++ b/crypto/x509/x509_vfy.h
@@ -263,6 +263,8 @@ struct x509_store_state_st /* X509_STORE_CTX */
#define X509_V_ERR_INVALID_CA 24
#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25
#define X509_V_ERR_INVALID_PURPOSE 26
+#define X509_V_ERR_CERT_UNTRUSTED 27
+#define X509_V_ERR_CERT_REJECTED 28
/* The application is not happy */
#define X509_V_ERR_APPLICATION_VERIFICATION 50
@@ -347,8 +349,9 @@ X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
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);
-void X509_STORE_CTX_chain_purpose(X509_STORE_CTX *ctx, int purpose);
+int X509_STORE_CTX_chain_purpose(X509_STORE_CTX *ctx, int purpose);
void X509_STORE_CTX_trust_purpose(X509_STORE_CTX *ctx, int purpose);
+int X509_set_purpose_and_trust(int id, int *purp, int *trust);
#ifdef __cplusplus
}