x509_vfy.c
来自「一个用于点对点传输加密的工具包源码」· C语言 代码 · 共 921 行 · 第 1/2 页
C
921 行
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; } if (X509_verify(xs,pkey) <= 0) { 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; } /* CRL CHECK */ /* 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; time_t 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; if (in_tm) t = *in_tm; else time(&t); t+=adj; if (!s) return ASN1_TIME_set(s, t); if (s->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_set(s,t); return ASN1_GENERALIZEDTIME_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) { x509_store_ctx_num++; return CRYPTO_get_ex_new_index(x509_store_ctx_num-1, &x509_store_ctx_method, 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 = purpose; if (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) 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);}void 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->purpose=0; ctx->trust=0; ctx->check_time=0; ctx->flags=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; ctx->check_issued = check_issued; ctx->get_issuer = X509_STORE_CTX_get1_issuer; ctx->verify_cb = store->verify_cb; ctx->verify = store->verify; ctx->cleanup = 0; memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); }/* 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(x509_store_ctx_method,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; }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 + =
减小字号Ctrl + -
显示快捷键?