⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 revoke.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (ret) {	hx509_set_error_string(context, HX509_ERROR_APPEND, ret,			       "CRL signature invalid");	goto out;    }    /*      * If signer is not CA cert, need to check revoke status of this     * CRL signing cert too, this include all parent CRL signer cert     * up to the root *sigh*, assume root at least hve CERTSIGN flag     * set.     */    while (_hx509_check_key_usage(context, signer, 1 << 5, TRUE)) {	hx509_cert crl_parent;	_hx509_query_clear(&q);		q.match = HX509_QUERY_MATCH_SUBJECT_NAME;	q.match |= HX509_QUERY_KU_CRLSIGN;	q.subject_name = &_hx509_get_cert(signer)->tbsCertificate.issuer;		ret = hx509_certs_find(context, certs, &q, &crl_parent);	if (ret) {	    hx509_set_error_string(context, HX509_ERROR_APPEND, ret,				   "Failed to find parent of CRL signer");	    goto out;	}	ret = hx509_revoke_verify(context,				  ctx, 				  certs,				  time_now,				  signer,				  crl_parent);	hx509_cert_free(signer);	signer = crl_parent;	if (ret) {	    hx509_set_error_string(context, HX509_ERROR_APPEND, ret,				   "Failed to verify revoke "				   "status of CRL signer");	    goto out;	}    }out:    hx509_cert_free(signer);    return ret;}static intload_crl(const char *path, time_t *t, CRLCertificateList *crl){    size_t length, size;    struct stat sb;    void *data;    int ret;    memset(crl, 0, sizeof(*crl));    ret = _hx509_map_file(path, &data, &length, &sb);    if (ret)	return ret;    *t = sb.st_mtime;    ret = decode_CRLCertificateList(data, length, crl, &size);    _hx509_unmap_file(data, length);    if (ret)	return ret;    /* check signature is aligned */    if (crl->signatureValue.length & 7) {	free_CRLCertificateList(crl);	return HX509_CRYPTO_SIG_INVALID_FORMAT;    }    return 0;}/** * Add a CRL file to the revokation context. * * @param context hx509 context * @param ctx hx509 revokation context * @param path path to file that is going to be added to the context. * * @return An hx509 error code, see hx509_get_error_string(). * * @ingroup hx509_revoke */inthx509_revoke_add_crl(hx509_context context,		     hx509_revoke_ctx ctx,		     const char *path){    void *data;    size_t i;    int ret;    if (strncmp(path, "FILE:", 5) != 0) {	hx509_set_error_string(context, 0, HX509_UNSUPPORTED_OPERATION,			       "unsupport type in %s", path);	return HX509_UNSUPPORTED_OPERATION;    }        path += 5;    for (i = 0; i < ctx->crls.len; i++) {	if (strcmp(ctx->crls.val[0].path, path) == 0)	    return 0;    }    data = realloc(ctx->crls.val, 		   (ctx->crls.len + 1) * sizeof(ctx->crls.val[0]));    if (data == NULL) {	hx509_clear_error_string(context);	return ENOMEM;    }    ctx->crls.val = data;    memset(&ctx->crls.val[ctx->crls.len], 0, sizeof(ctx->crls.val[0]));    ctx->crls.val[ctx->crls.len].path = strdup(path);    if (ctx->crls.val[ctx->crls.len].path == NULL) {	hx509_clear_error_string(context);	return ENOMEM;    }    ret = load_crl(path, 		   &ctx->crls.val[ctx->crls.len].last_modfied,		   &ctx->crls.val[ctx->crls.len].crl);    if (ret) {	free(ctx->crls.val[ctx->crls.len].path);	return ret;    }    ctx->crls.len++;    return ret;}/** * Check that a certificate is not expired according to a revokation * context. Also need the parent certificte to the check OCSP * parent identifier. * * @param context hx509 context * @param ctx hx509 revokation context * @param certs * @param now * @param cert * @param parent_cert * * @return An hx509 error code, see hx509_get_error_string(). * * @ingroup hx509_revoke */inthx509_revoke_verify(hx509_context context,		    hx509_revoke_ctx ctx,		    hx509_certs certs,		    time_t now,		    hx509_cert cert,		    hx509_cert parent_cert){    const Certificate *c = _hx509_get_cert(cert);    const Certificate *p = _hx509_get_cert(parent_cert);    unsigned long i, j, k;    int ret;    hx509_clear_error_string(context);    for (i = 0; i < ctx->ocsps.len; i++) {	struct revoke_ocsp *ocsp = &ctx->ocsps.val[i];	struct stat sb;	/* check this ocsp apply to this cert */	/* check if there is a newer version of the file */	ret = stat(ocsp->path, &sb);	if (ret == 0 && ocsp->last_modfied != sb.st_mtime) {	    ret = load_ocsp(context, ocsp);	    if (ret)		continue;	}	/* verify signature in ocsp if not already done */	if (ocsp->signer == NULL) {	    ret = verify_ocsp(context, ocsp, now, certs, parent_cert);	    if (ret)		continue;	}	for (j = 0; j < ocsp->ocsp.tbsResponseData.responses.len; j++) {	    heim_octet_string os;	    ret = der_heim_integer_cmp(&ocsp->ocsp.tbsResponseData.responses.val[j].certID.serialNumber,				   &c->tbsCertificate.serialNumber);	    if (ret != 0)		continue;	    	    /* verify issuer hashes hash */	    ret = _hx509_verify_signature(context,					  NULL,					  &ocsp->ocsp.tbsResponseData.responses.val[i].certID.hashAlgorithm,					  &c->tbsCertificate.issuer._save,					  &ocsp->ocsp.tbsResponseData.responses.val[i].certID.issuerNameHash);	    if (ret != 0)		continue;	    os.data = p->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data;	    os.length = p->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.length / 8;	    ret = _hx509_verify_signature(context,					  NULL,					  &ocsp->ocsp.tbsResponseData.responses.val[j].certID.hashAlgorithm,					  &os,					  &ocsp->ocsp.tbsResponseData.responses.val[j].certID.issuerKeyHash);	    if (ret != 0)		continue;	    switch (ocsp->ocsp.tbsResponseData.responses.val[j].certStatus.element) {	    case choice_OCSPCertStatus_good:		break;	    case choice_OCSPCertStatus_revoked:		hx509_set_error_string(context, 0, 				       HX509_CERT_REVOKED,				       "Certificate revoked by issuer in OCSP");		return HX509_CERT_REVOKED;	    case choice_OCSPCertStatus_unknown:		continue;	    }	    /* don't allow the update to be in the future */	    if (ocsp->ocsp.tbsResponseData.responses.val[j].thisUpdate > 		now + context->ocsp_time_diff)		continue;	    /* don't allow the next update to be in the past */	    if (ocsp->ocsp.tbsResponseData.responses.val[j].nextUpdate) {		if (*ocsp->ocsp.tbsResponseData.responses.val[j].nextUpdate < now)		    continue;	    } else		/* Should force a refetch, but can we ? */;	    return 0;	}    }    for (i = 0; i < ctx->crls.len; i++) {	struct revoke_crl *crl = &ctx->crls.val[i];	struct stat sb;	int diff;	/* check if cert.issuer == crls.val[i].crl.issuer */	ret = _hx509_name_cmp(&c->tbsCertificate.issuer, 			      &crl->crl.tbsCertList.issuer, &diff);	if (ret || diff)	    continue;	ret = stat(crl->path, &sb);	if (ret == 0 && crl->last_modfied != sb.st_mtime) {	    CRLCertificateList cl;	    ret = load_crl(crl->path, &crl->last_modfied, &cl);	    if (ret == 0) {		free_CRLCertificateList(&crl->crl);		crl->crl = cl;		crl->verified = 0;		crl->failed_verify = 0;	    }	}	if (crl->failed_verify)	    continue;	/* verify signature in crl if not already done */	if (crl->verified == 0) {	    ret = verify_crl(context, ctx, &crl->crl, now, certs, parent_cert);	    if (ret) {		crl->failed_verify = 1;		continue;	    }	    crl->verified = 1;	}	if (crl->crl.tbsCertList.crlExtensions) {	    for (j = 0; j < crl->crl.tbsCertList.crlExtensions->len; j++) {		if (crl->crl.tbsCertList.crlExtensions->val[j].critical) {		    hx509_set_error_string(context, 0, 					   HX509_CRL_UNKNOWN_EXTENSION,					   "Unknown CRL extension");		    return HX509_CRL_UNKNOWN_EXTENSION;		}	    }	}	if (crl->crl.tbsCertList.revokedCertificates == NULL)	    return 0;	/* check if cert is in crl */	for (j = 0; j < crl->crl.tbsCertList.revokedCertificates->len; j++) {	    time_t t;	    ret = der_heim_integer_cmp(&crl->crl.tbsCertList.revokedCertificates->val[j].userCertificate,				       &c->tbsCertificate.serialNumber);	    if (ret != 0)		continue;	    t = _hx509_Time2time_t(&crl->crl.tbsCertList.revokedCertificates->val[j].revocationDate);	    if (t > now)		continue;	    	    if (crl->crl.tbsCertList.revokedCertificates->val[j].crlEntryExtensions)		for (k = 0; k < crl->crl.tbsCertList.revokedCertificates->val[j].crlEntryExtensions->len; k++)		    if (crl->crl.tbsCertList.revokedCertificates->val[j].crlEntryExtensions->val[k].critical)			return HX509_CRL_UNKNOWN_EXTENSION;	    	    hx509_set_error_string(context, 0, 				   HX509_CERT_REVOKED,				   "Certificate revoked by issuer in CRL");	    return HX509_CERT_REVOKED;	}	return 0;    }    if (context->flags & HX509_CTX_VERIFY_MISSING_OK)	return 0;    hx509_set_error_string(context, HX509_ERROR_APPEND, 			   HX509_REVOKE_STATUS_MISSING,			   "No revoke status found for "			   "certificates");    return HX509_REVOKE_STATUS_MISSING;}struct ocsp_add_ctx {    OCSPTBSRequest *req;    hx509_certs certs;    const AlgorithmIdentifier *digest;    hx509_cert parent;};static intadd_to_req(hx509_context context, void *ptr, hx509_cert cert){    struct ocsp_add_ctx *ctx = ptr;    OCSPInnerRequest *one;    hx509_cert parent = NULL;    Certificate *p, *c = _hx509_get_cert(cert);    heim_octet_string os;    int ret;    hx509_query q;    void *d;    d = realloc(ctx->req->requestList.val, 		sizeof(ctx->req->requestList.val[0]) *		(ctx->req->requestList.len + 1));    if (d == NULL)	return ENOMEM;    ctx->req->requestList.val = d;        one = &ctx->req->requestList.val[ctx->req->requestList.len];    memset(one, 0, sizeof(*one));    _hx509_query_clear(&q);    q.match |= HX509_QUERY_FIND_ISSUER_CERT;    q.subject = c;    ret = hx509_certs_find(context, ctx->certs, &q, &parent);    if (ret)	goto out;    if (ctx->parent) {	if (hx509_cert_cmp(ctx->parent, parent) != 0) {	    ret = HX509_REVOKE_NOT_SAME_PARENT;	    hx509_set_error_string(context, 0, ret,				   "Not same parent certifate as "				   "last certificate in request");	    goto out;	}    } else	ctx->parent = hx509_cert_ref(parent);    p = _hx509_get_cert(parent);    ret = copy_AlgorithmIdentifier(ctx->digest, &one->reqCert.hashAlgorithm);    if (ret)	goto out;    ret = _hx509_create_signature(context,				  NULL,				  &one->reqCert.hashAlgorithm,				  &c->tbsCertificate.issuer._save,				  NULL,				  &one->reqCert.issuerNameHash);    if (ret)	goto out;    os.data = p->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data;    os.length = 	p->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.length / 8;    ret = _hx509_create_signature(context,				  NULL,				  &one->reqCert.hashAlgorithm,				  &os,				  NULL,				  &one->reqCert.issuerKeyHash);    if (ret)	goto out;    ret = copy_CertificateSerialNumber(&c->tbsCertificate.serialNumber,				       &one->reqCert.serialNumber);    if (ret)	goto out;    ctx->req->requestList.len++;out:    hx509_cert_free(parent);    if (ret) {	free_OCSPInnerRequest(one);	memset(one, 0, sizeof(*one));    }    return ret;}/** * Create an OCSP request for a set of certificates. * * @param context a hx509 context * @param reqcerts list of certificates to request ocsp data for * @param pool certificate pool to use when signing * @param signer certificate to use to sign the request * @param digest the signing algorithm in the request, if NULL use the * default signature algorithm, * @param request the encoded request, free with free_heim_octet_string(). * @param nonce nonce in the request, free with free_heim_octet_string(). * * @return An hx509 error code, see hx509_get_error_string(). * * @ingroup hx509_revoke */inthx509_ocsp_request(hx509_context context,		   hx509_certs reqcerts,		   hx509_certs pool,		   hx509_cert signer,		   const AlgorithmIdentifier *digest,		   heim_octet_string *request,		   heim_octet_string *nonce){    OCSPRequest req;    size_t size;    int ret;    struct ocsp_add_ctx ctx;    Extensions *es;    memset(&req, 0, sizeof(req));    if (digest == NULL)	digest = _hx509_crypto_default_digest_alg;    ctx.req = &req.tbsRequest;    ctx.certs = pool;    ctx.digest = digest;    ctx.parent = NULL;    ret = hx509_certs_iter(context, reqcerts, add_to_req, &ctx);    hx509_cert_free(ctx.parent);    if (ret)	goto out;        if (nonce) {	req.tbsRequest.requestExtensions = 	    calloc(1, sizeof(*req.tbsRequest.requestExtensions));	if (req.tbsRequest.requestExtensions == NULL) {	    ret = ENOMEM;	    goto out;	}	es = req.tbsRequest.requestExtensions;		es->val = calloc(es->len, sizeof(es->val[0]));	if (es->val == NULL) {	    ret = ENOMEM;	    goto out;	}	es->len = 1;		ret = der_copy_oid(oid_id_pkix_ocsp_nonce(), &es->val[0].extnID);	if (ret) {	    free_OCSPRequest(&req);	    return ret;	}	es->val[0].extnValue.data = malloc(10);	if (es->val[0].extnValue.data == NULL) {	    ret = ENOMEM;	    goto out;	}	es->val[0].extnValue.length = 10;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -