📄 x509_vfy.c
字号:
err: EVP_PKEY_free(ikey); return ok; }/* Check certificate against CRL */static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) { int idx, ok; X509_REVOKED rtmp; STACK_OF(X509_EXTENSION) *exts; X509_EXTENSION *ext; /* Look for serial number of certificate in CRL */ rtmp.serialNumber = X509_get_serialNumber(x); idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); /* If found assume revoked: want something cleverer than * this to handle entry extensions in V2 CRLs. */ if(idx >= 0) { ctx->error = X509_V_ERR_CERT_REVOKED; ok = ctx->verify_cb(0, ctx); if (!ok) return 0; } if (ctx->flags & X509_V_FLAG_IGNORE_CRITICAL) return 1; /* See if we have any critical CRL extensions: since we * currently don't handle any CRL extensions the CRL must be * rejected. * This code accesses the X509_CRL structure directly: applications * shouldn't do this. */ exts = crl->crl->extensions; for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) { ext = sk_X509_EXTENSION_value(exts, idx); if (ext->critical > 0) { ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; ok = ctx->verify_cb(0, ctx); if(!ok) return 0; break; } } return 1; }static int internal_verify(X509_STORE_CTX *ctx) { int i,ok=0,n; X509 *xs,*xi; EVP_PKEY *pkey=NULL; time_t *ptime; int (*cb)(); cb=ctx->verify_cb; n=sk_X509_num(ctx->chain); ctx->error_depth=n-1; n--; xi=sk_X509_value(ctx->chain,n); if (ctx->flags & X509_V_FLAG_USE_CHECK_TIME) ptime = &ctx->check_time; else ptime = NULL; if (ctx->check_issued(ctx, xi, xi)) xs=xi; else { if (n <= 0) { ctx->error=X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; ctx->current_cert=xi; ok=cb(0,ctx); goto end; } else { n--; ctx->error_depth=n; xs=sk_X509_value(ctx->chain,n); } }/* ctx->error=0; not needed */ while (n >= 0) { ctx->error_depth=n; if (!xs->valid) { if ((pkey=X509_get_pubkey(xi)) == NULL) { ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; ctx->current_cert=xi; ok=(*cb)(0,ctx); if (!ok) goto end; } else if (X509_verify(xs,pkey) <= 0) /* XXX For the final trusted self-signed cert, * this is a waste of time. That check should * optional so that e.g. 'openssl x509' can be * used to detect invalid self-signatures, but * we don't verify again and again in SSL * handshakes and the like once the cert has * been declared trusted. */ { ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE; ctx->current_cert=xs; ok=(*cb)(0,ctx); if (!ok) { EVP_PKEY_free(pkey); goto end; } } EVP_PKEY_free(pkey); pkey=NULL; i=X509_cmp_time(X509_get_notBefore(xs), ptime); if (i == 0) { ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; ctx->current_cert=xs; ok=(*cb)(0,ctx); if (!ok) goto end; } if (i > 0) { ctx->error=X509_V_ERR_CERT_NOT_YET_VALID; ctx->current_cert=xs; ok=(*cb)(0,ctx); if (!ok) goto end; } xs->valid=1; } i=X509_cmp_time(X509_get_notAfter(xs), ptime); if (i == 0) { ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; ctx->current_cert=xs; ok=(*cb)(0,ctx); if (!ok) goto end; } if (i < 0) { ctx->error=X509_V_ERR_CERT_HAS_EXPIRED; ctx->current_cert=xs; ok=(*cb)(0,ctx); if (!ok) goto end; } /* The last error (if any) is still in the error value */ ctx->current_cert=xs; ok=(*cb)(1,ctx); if (!ok) goto end; n--; if (n >= 0) { xi=xs; xs=sk_X509_value(ctx->chain,n); } } ok=1;end: return ok; }int X509_cmp_current_time(ASN1_TIME *ctm){ return X509_cmp_time(ctm, NULL);}int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time) { char *str; ASN1_TIME atm; long offset; char buff1[24],buff2[24],*p; int i,j; p=buff1; i=ctm->length; str=(char *)ctm->data; if (ctm->type == V_ASN1_UTCTIME) { if ((i < 11) || (i > 17)) return 0; memcpy(p,str,10); p+=10; str+=10; } else { if (i < 13) return 0; memcpy(p,str,12); p+=12; str+=12; } if ((*str == 'Z') || (*str == '-') || (*str == '+')) { *(p++)='0'; *(p++)='0'; } else { *(p++)= *(str++); *(p++)= *(str++); /* Skip any fractional seconds... */ if (*str == '.') { str++; while ((*str >= '0') && (*str <= '9')) str++; } } *(p++)='Z'; *(p++)='\0'; if (*str == 'Z') offset=0; else { if ((*str != '+') && (str[5] != '-')) return 0; offset=((str[1]-'0')*10+(str[2]-'0'))*60; offset+=(str[3]-'0')*10+(str[4]-'0'); if (*str == '-') offset= -offset; } atm.type=ctm->type; atm.length=sizeof(buff2); atm.data=(unsigned char *)buff2; X509_time_adj(&atm,-offset*60, cmp_time); if (ctm->type == V_ASN1_UTCTIME) { i=(buff1[0]-'0')*10+(buff1[1]-'0'); if (i < 50) i+=100; /* cf. RFC 2459 */ j=(buff2[0]-'0')*10+(buff2[1]-'0'); if (j < 50) j+=100; if (i < j) return -1; if (i > j) return 1; } i=strcmp(buff1,buff2); if (i == 0) /* wait a second then return younger :-) */ return -1; else return i; }ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj){ return X509_time_adj(s, adj, NULL);}ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *in_tm) { time_t t; int type = -1; if (in_tm) t = *in_tm; else time(&t); t+=adj; if (s) type = s->type; if (type == V_ASN1_UTCTIME) return ASN1_UTCTIME_set(s,t); if (type == V_ASN1_GENERALIZEDTIME) return ASN1_GENERALIZEDTIME_set(s, t); return ASN1_TIME_set(s, t); }int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) { EVP_PKEY *ktmp=NULL,*ktmp2; int i,j; if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) return 1; for (i=0; i<sk_X509_num(chain); i++) { ktmp=X509_get_pubkey(sk_X509_value(chain,i)); if (ktmp == NULL) { X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); return 0; } if (!EVP_PKEY_missing_parameters(ktmp)) break; else { EVP_PKEY_free(ktmp); ktmp=NULL; } } if (ktmp == NULL) { X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN); return 0; } /* first, populate the other certs */ for (j=i-1; j >= 0; j--) { ktmp2=X509_get_pubkey(sk_X509_value(chain,j)); EVP_PKEY_copy_parameters(ktmp2,ktmp); EVP_PKEY_free(ktmp2); } if (pkey != NULL) EVP_PKEY_copy_parameters(pkey,ktmp); EVP_PKEY_free(ktmp); return 1; }int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { /* This function is (usually) called only once, by * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */ return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp, new_func, dup_func, free_func); }int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) { return CRYPTO_set_ex_data(&ctx->ex_data,idx,data); }void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) { return CRYPTO_get_ex_data(&ctx->ex_data,idx); }int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) { return ctx->error; }void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) { ctx->error=err; }int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) { return ctx->error_depth; }X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) { return ctx->current_cert; }STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) { return ctx->chain; }STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) { int i; X509 *x; STACK_OF(X509) *chain; if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain))) return NULL; for (i = 0; i < sk_X509_num(chain); i++) { x = sk_X509_value(chain, i); CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); } return chain; }void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) { ctx->cert=x; }void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) { ctx->untrusted=sk; }int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) { return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); }int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) { return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); }/* This function is used to set the X509_STORE_CTX purpose and trust * values. This is intended to be used when another structure has its * own trust and purpose values which (if set) will be inherited by * the ctx. If they aren't set then we will usually have a default * purpose in mind which should then be used to set the trust value. * An example of this is SSL use: an SSL structure will have its own * purpose and trust settings which the application can set: if they * aren't set then we use the default of SSL client/server. */int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, int purpose, int trust){ int idx; /* If purpose not set use default */ if (!purpose) purpose = def_purpose; /* If we have a purpose then check it is valid */ if (purpose) { X509_PURPOSE *ptmp; idx = X509_PURPOSE_get_by_id(purpose); if (idx == -1) { X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, X509_R_UNKNOWN_PURPOSE_ID); return 0; } ptmp = X509_PURPOSE_get0(idx); if (ptmp->trust == X509_TRUST_DEFAULT) { idx = X509_PURPOSE_get_by_id(def_purpose); if (idx == -1) { X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, X509_R_UNKNOWN_PURPOSE_ID); return 0; } ptmp = X509_PURPOSE_get0(idx); } /* If trust not set then get from purpose default */ if (!trust) trust = ptmp->trust; } if (trust) { idx = X509_TRUST_get_by_id(trust); if (idx == -1) { X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, X509_R_UNKNOWN_TRUST_ID); return 0; } } if (purpose && !ctx->purpose) ctx->purpose = purpose; if (trust && !ctx->trust) ctx->trust = trust; return 1;}X509_STORE_CTX *X509_STORE_CTX_new(void){ X509_STORE_CTX *ctx; ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX)); if (!ctx) { X509err(X509_F_X509_STORE_CTX_NEW,ERR_R_MALLOC_FAILURE); return NULL; } memset(ctx, 0, sizeof(X509_STORE_CTX)); return ctx;}void X509_STORE_CTX_free(X509_STORE_CTX *ctx){ X509_STORE_CTX_cleanup(ctx); OPENSSL_free(ctx);}int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, STACK_OF(X509) *chain) { ctx->ctx=store; ctx->current_method=0; ctx->cert=x509; ctx->untrusted=chain; ctx->last_untrusted=0; ctx->check_time=0; ctx->other_ctx=NULL; ctx->valid=0; ctx->chain=NULL; ctx->depth=9; ctx->error=0; ctx->error_depth=0; ctx->current_cert=NULL; ctx->current_issuer=NULL; /* Inherit callbacks and flags from X509_STORE if not set * use defaults. */ if (store) { ctx->purpose=store->purpose; ctx->trust=store->trust; ctx->flags = store->flags; ctx->cleanup = store->cleanup; } else { ctx->purpose = 0; ctx->trust = 0; ctx->flags = 0; ctx->cleanup = 0; } if (store && store->check_issued) ctx->check_issued = store->check_issued; else ctx->check_issued = check_issued; if (store && store->get_issuer) ctx->get_issuer = store->get_issuer; else ctx->get_issuer = X509_STORE_CTX_get1_issuer; if (store && store->verify_cb) ctx->verify_cb = store->verify_cb; else ctx->verify_cb = null_callback; if (store && store->verify) ctx->verify = store->verify; else ctx->verify = internal_verify; if (store && store->check_revocation) ctx->check_revocation = store->check_revocation; else ctx->check_revocation = check_revocation; if (store && store->get_crl) ctx->get_crl = store->get_crl; else ctx->get_crl = get_crl; if (store && store->check_crl) ctx->check_crl = store->check_crl; else ctx->check_crl = check_crl; if (store && store->cert_crl) ctx->cert_crl = store->cert_crl; else ctx->cert_crl = cert_crl; /* This memset() can't make any sense anyway, so it's removed. As * X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a * corresponding "new" here and remove this bogus initialisation. */ /* memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); */ if(!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data))) { OPENSSL_free(ctx); X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE); return 0; } return 1; }/* Set alternative lookup method: just a STACK of trusted certificates. * This avoids X509_STORE nastiness where it isn't needed. */void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk){ ctx->other_ctx = sk; ctx->get_issuer = get_issuer_sk;}void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) { if (ctx->cleanup) ctx->cleanup(ctx); if (ctx->chain != NULL) { sk_X509_pop_free(ctx->chain,X509_free); ctx->chain=NULL; } CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data)); memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA)); }void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, long flags) { ctx->flags |= flags; }void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, long flags, time_t t) { ctx->check_time = t; ctx->flags |= X509_V_FLAG_USE_CHECK_TIME; }void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, int (*verify_cb)(int, X509_STORE_CTX *)) { ctx->verify_cb=verify_cb; }IMPLEMENT_STACK_OF(X509)IMPLEMENT_ASN1_SET_OF(X509)IMPLEMENT_STACK_OF(X509_NAME)IMPLEMENT_STACK_OF(X509_ATTRIBUTE)IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -