static int KSI_PKITruststore_verifySignatureCertificate(const KSI_PKITruststore *pki, const KSI_PKISignature *signature) { int res = KSI_UNKNOWN_ERROR; KSI_CTX *ctx = NULL; PCCERT_CONTEXT subjectCert = NULL; char tmp[256]; char *magicEmail = NULL; if (pki == NULL || signature == NULL){ res = KSI_INVALID_ARGUMENT; goto cleanup; } ctx = pki->ctx; KSI_ERR_clearErrors(ctx); res = extractSigningCertificate(signature, &subjectCert); if (res != KSI_OK){ KSI_pushError(ctx, res, NULL); goto cleanup; } //printCertInfo(subjectCert); res=KSI_CTX_getPublicationCertEmail(ctx, &magicEmail); if (res != KSI_OK){ KSI_pushError(ctx, res, NULL); goto cleanup; } if (magicEmail != NULL){ if (CertGetNameString(subjectCert, CERT_NAME_EMAIL_TYPE, 0, NULL, tmp, sizeof(tmp))==1){ KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to get subjects name from PKI certificate."); goto cleanup; } KSI_LOG_debug(ctx, "CryptoAPI: Subjects E-mail: %s.", tmp); if (strcmp(tmp, magicEmail) != 0) { KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, "Wrong subject name."); goto cleanup; } } res = KSI_PKITruststore_verifyCertificate(pki, subjectCert); if (res != KSI_OK){ KSI_pushError(ctx, res, NULL); goto cleanup; } res = KSI_OK; cleanup: if (subjectCert) CertFreeCertificateContext(subjectCert); return res; }
static int KSI_PKITruststore_verifySignatureCertificate(const KSI_PKITruststore *pki, const KSI_PKISignature *signature) { int res = KSI_UNKNOWN_ERROR; KSI_CTX *ctx = NULL; PCCERT_CONTEXT subjectCert = NULL; char tmp[256]; size_t i; if (pki == NULL || signature == NULL){ res = KSI_INVALID_ARGUMENT; goto cleanup; } ctx = pki->ctx; KSI_ERR_clearErrors(ctx); res = extractSigningCertificate(signature, &subjectCert); if (res != KSI_OK){ KSI_pushError(ctx, res, NULL); goto cleanup; } for (i = 0; pki->ctx->certConstraints[i].oid != NULL; i++) { KSI_CertConstraint *ptr = &pki->ctx->certConstraints[i]; KSI_LOG_info(pki->ctx, "Verifying PKI signature certificate with oid = '%s' expected value '%s'.", ptr->oid, ptr->val); if (CertGetNameString(subjectCert, CERT_NAME_ATTR_TYPE, 0, ptr->oid, tmp, sizeof(tmp)) == 1){ KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to get OID value."); goto cleanup; } if (strcmp(tmp, ptr->val) != 0) { KSI_LOG_debug(pki->ctx, "Unexpected value for OID='%s': '%s'", ptr->oid, tmp); KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, "Unexpected OID value."); goto cleanup; } } res = KSI_PKITruststore_verifyCertificate(pki, subjectCert); if (res != KSI_OK){ KSI_pushError(ctx, res, NULL); goto cleanup; } res = KSI_OK; cleanup: if (subjectCert) CertFreeCertificateContext(subjectCert); return res; }
int KSI_PKITruststore_verifySignature(KSI_PKITruststore *pki, const unsigned char *data, size_t data_len, const KSI_PKISignature *signature) { int res = KSI_UNKNOWN_ERROR; KSI_CTX *ctx = NULL; PCCERT_CONTEXT subjectCert = NULL; CRYPT_VERIFY_MESSAGE_PARA msgPara; DWORD dLen; char buf[1024]; if (pki == NULL || data == NULL || signature == NULL){ res = KSI_INVALID_ARGUMENT; goto cleanup; } ctx = pki->ctx; KSI_ERR_clearErrors(ctx); KSI_LOG_debug(ctx, "CryptoAPI: Start PKI signature verification."); if (data_len > INT_MAX) { KSI_pushError(ctx, res = KSI_INVALID_ARGUMENT, "Data too long (more than MAX_INT)."); goto cleanup; } /*Verify signature and signed data. Certificate is extracted from signature*/ msgPara.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA); msgPara.dwMsgAndCertEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; msgPara.hCryptProv = 0; msgPara.pfnGetSignerCertificate = NULL; msgPara.pvGetArg = NULL; dLen = (DWORD)data_len; if (!CryptVerifyDetachedMessageSignature(&msgPara, 0, signature->pkcs7.pbData, signature->pkcs7.cbData, 1, &data, &dLen, &subjectCert)){ DWORD error = GetLastError(); const char *errmsg = getMSError(error, buf, sizeof(buf)); KSI_LOG_debug(pki->ctx, "%s", errmsg); if (error == E_INVALIDARG || error == CRYPT_E_UNEXPECTED_MSG_TYPE || error == CRYPT_E_NO_SIGNER) KSI_pushError(ctx, res = KSI_INVALID_FORMAT, errmsg); else if (error == NTE_BAD_ALGID) KSI_pushError(ctx, res = KSI_INVALID_PKI_SIGNATURE, errmsg); else if (error == NTE_BAD_SIGNATURE) KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Verification of PKI signature failed."); else KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, errmsg); goto cleanup; } res = KSI_PKITruststore_verifyCertificate(pki, subjectCert); if (res != KSI_OK){ KSI_pushError(ctx, res, NULL); goto cleanup; } res = KSI_PKITruststore_verifySignatureCertificate(pki, signature); if (res != KSI_OK){ KSI_pushError(ctx, res, NULL); goto cleanup; } KSI_LOG_debug(ctx, "CryptoAPI: PKI signature verified successfully."); res = KSI_OK; cleanup: if (subjectCert) CertFreeCertificateContext(subjectCert); return res; }