diff options
Diffstat (limited to 'thirdparty/openssl/crypto/ts/ts_rsp_verify.c')
-rw-r--r-- | thirdparty/openssl/crypto/ts/ts_rsp_verify.c | 746 |
1 files changed, 0 insertions, 746 deletions
diff --git a/thirdparty/openssl/crypto/ts/ts_rsp_verify.c b/thirdparty/openssl/crypto/ts/ts_rsp_verify.c deleted file mode 100644 index 7918236287..0000000000 --- a/thirdparty/openssl/crypto/ts/ts_rsp_verify.c +++ /dev/null @@ -1,746 +0,0 @@ -/* crypto/ts/ts_resp_verify.c */ -/* - * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project - * 2002. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include <stdio.h> -#include "cryptlib.h" -#include <openssl/objects.h> -#include <openssl/ts.h> -#include <openssl/pkcs7.h> - -/* Private function declarations. */ - -static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, - X509 *signer, STACK_OF(X509) **chain); -static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, - STACK_OF(X509) *chain); -static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si); -static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); -static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo); -static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, - PKCS7 *token, TS_TST_INFO *tst_info); -static int TS_check_status_info(TS_RESP *response); -static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text); -static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info); -static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, - X509_ALGOR **md_alg, - unsigned char **imprint, unsigned *imprint_len); -static int TS_check_imprints(X509_ALGOR *algor_a, - unsigned char *imprint_a, unsigned len_a, - TS_TST_INFO *tst_info); -static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info); -static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer); -static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, - GENERAL_NAME *name); - -/* - * Local mapping between response codes and descriptions. - * Don't forget to change TS_STATUS_BUF_SIZE when modifying - * the elements of this array. - */ -static const char *TS_status_text[] = { "granted", - "grantedWithMods", - "rejection", - "waiting", - "revocationWarning", - "revocationNotification" -}; - -#define TS_STATUS_TEXT_SIZE (sizeof(TS_status_text)/sizeof(*TS_status_text)) - -/* - * This must be greater or equal to the sum of the strings in TS_status_text - * plus the number of its elements. - */ -#define TS_STATUS_BUF_SIZE 256 - -static struct { - int code; - const char *text; -} TS_failure_info[] = { - { - TS_INFO_BAD_ALG, "badAlg" - }, - { - TS_INFO_BAD_REQUEST, "badRequest" - }, - { - TS_INFO_BAD_DATA_FORMAT, "badDataFormat" - }, - { - TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" - }, - { - TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" - }, - { - TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" - }, - { - TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" - }, - { - TS_INFO_SYSTEM_FAILURE, "systemFailure" - } -}; - -#define TS_FAILURE_INFO_SIZE (sizeof(TS_failure_info) / \ - sizeof(*TS_failure_info)) - -/* Functions for verifying a signed TS_TST_INFO structure. */ - -/*- - * This function carries out the following tasks: - * - Checks if there is one and only one signer. - * - Search for the signing certificate in 'certs' and in the response. - * - Check the extended key usage and key usage fields of the signer - * certificate (done by the path validation). - * - Build and validate the certificate path. - * - Check if the certificate path meets the requirements of the - * SigningCertificate ESS signed attribute. - * - Verify the signature value. - * - Returns the signer certificate in 'signer', if 'signer' is not NULL. - */ -int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, - X509_STORE *store, X509 **signer_out) -{ - STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL; - PKCS7_SIGNER_INFO *si; - STACK_OF(X509) *signers = NULL; - X509 *signer; - STACK_OF(X509) *chain = NULL; - char buf[4096]; - int i, j = 0, ret = 0; - BIO *p7bio = NULL; - - /* Some sanity checks first. */ - if (!token) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER); - goto err; - } - - /* Check for the correct content type */ - if (!PKCS7_type_is_signed(token)) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE); - goto err; - } - - /* Check if there is one and only one signer. */ - sinfos = PKCS7_get_signer_info(token); - if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_THERE_MUST_BE_ONE_SIGNER); - goto err; - } - si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0); - - /* Check for no content: no data to verify signature. */ - if (PKCS7_get_detached(token)) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT); - goto err; - } - - /* - * Get hold of the signer certificate, search only internal certificates - * if it was requested. - */ - signers = PKCS7_get0_signers(token, certs, 0); - if (!signers || sk_X509_num(signers) != 1) - goto err; - signer = sk_X509_value(signers, 0); - - /* Now verify the certificate. */ - if (!TS_verify_cert(store, certs, signer, &chain)) - goto err; - - /* - * Check if the signer certificate is consistent with the ESS extension. - */ - if (!TS_check_signing_certs(si, chain)) - goto err; - - /* Creating the message digest. */ - p7bio = PKCS7_dataInit(token, NULL); - - /* We now have to 'read' from p7bio to calculate digests etc. */ - while ((i = BIO_read(p7bio, buf, sizeof(buf))) > 0) ; - - /* Verifying the signature. */ - j = PKCS7_signatureVerify(p7bio, token, si, signer); - if (j <= 0) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE); - goto err; - } - - /* Return the signer certificate if needed. */ - if (signer_out) { - *signer_out = signer; - CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); - } - - ret = 1; - - err: - BIO_free_all(p7bio); - sk_X509_pop_free(chain, X509_free); - sk_X509_free(signers); - - return ret; -} - -/* - * The certificate chain is returned in chain. Caller is responsible for - * freeing the vector. - */ -static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, - X509 *signer, STACK_OF(X509) **chain) -{ - X509_STORE_CTX cert_ctx; - int i; - int ret = 1; - - /* chain is an out argument. */ - *chain = NULL; - if (!X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted)) - return 0; - X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN); - i = X509_verify_cert(&cert_ctx); - if (i <= 0) { - int j = X509_STORE_CTX_get_error(&cert_ctx); - TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(j)); - ret = 0; - } else { - /* Get a copy of the certificate chain. */ - *chain = X509_STORE_CTX_get1_chain(&cert_ctx); - } - - X509_STORE_CTX_cleanup(&cert_ctx); - - return ret; -} - -static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, - STACK_OF(X509) *chain) -{ - ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si); - STACK_OF(ESS_CERT_ID) *cert_ids = NULL; - X509 *cert; - int i = 0; - int ret = 0; - - if (!ss) - goto err; - cert_ids = ss->cert_ids; - /* The signer certificate must be the first in cert_ids. */ - cert = sk_X509_value(chain, 0); - if (TS_find_cert(cert_ids, cert) != 0) - goto err; - - /* - * Check the other certificates of the chain if there are more than one - * certificate ids in cert_ids. - */ - if (sk_ESS_CERT_ID_num(cert_ids) > 1) { - /* All the certificates of the chain must be in cert_ids. */ - for (i = 1; i < sk_X509_num(chain); ++i) { - cert = sk_X509_value(chain, i); - if (TS_find_cert(cert_ids, cert) < 0) - goto err; - } - } - ret = 1; - err: - if (!ret) - TSerr(TS_F_TS_CHECK_SIGNING_CERTS, - TS_R_ESS_SIGNING_CERTIFICATE_ERROR); - ESS_SIGNING_CERT_free(ss); - return ret; -} - -static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si) -{ - ASN1_TYPE *attr; - const unsigned char *p; - attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate); - if (!attr) - return NULL; - p = attr->value.sequence->data; - return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length); -} - -/* Returns < 0 if certificate is not found, certificate index otherwise. */ -static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) -{ - int i; - - if (!cert_ids || !cert) - return -1; - - /* Recompute SHA1 hash of certificate if necessary (side effect). */ - X509_check_purpose(cert, -1, 0); - - /* Look for cert in the cert_ids vector. */ - for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) { - ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); - - /* Check the SHA-1 hash first. */ - if (cid->hash->length == sizeof(cert->sha1_hash) - && !memcmp(cid->hash->data, cert->sha1_hash, - sizeof(cert->sha1_hash))) { - /* Check the issuer/serial as well if specified. */ - ESS_ISSUER_SERIAL *is = cid->issuer_serial; - if (!is || !TS_issuer_serial_cmp(is, cert->cert_info)) - return i; - } - } - - return -1; -} - -static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo) -{ - GENERAL_NAME *issuer; - - if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1) - return -1; - - /* Check the issuer first. It must be a directory name. */ - issuer = sk_GENERAL_NAME_value(is->issuer, 0); - if (issuer->type != GEN_DIRNAME - || X509_NAME_cmp(issuer->d.dirn, cinfo->issuer)) - return -1; - - /* Check the serial number, too. */ - if (ASN1_INTEGER_cmp(is->serial, cinfo->serialNumber)) - return -1; - - return 0; -} - -/*- - * Verifies whether 'response' contains a valid response with regards - * to the settings of the context: - * - Gives an error message if the TS_TST_INFO is not present. - * - Calls _TS_RESP_verify_token to verify the token content. - */ -int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response) -{ - PKCS7 *token = TS_RESP_get_token(response); - TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); - int ret = 0; - - /* Check if we have a successful TS_TST_INFO object in place. */ - if (!TS_check_status_info(response)) - goto err; - - /* Check the contents of the time stamp token. */ - if (!int_TS_RESP_verify_token(ctx, token, tst_info)) - goto err; - - ret = 1; - err: - return ret; -} - -/* - * Tries to extract a TS_TST_INFO structure from the PKCS7 token and - * calls the internal int_TS_RESP_verify_token function for verifying it. - */ -int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token) -{ - TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token); - int ret = 0; - if (tst_info) { - ret = int_TS_RESP_verify_token(ctx, token, tst_info); - TS_TST_INFO_free(tst_info); - } - return ret; -} - -/*- - * Verifies whether the 'token' contains a valid time stamp token - * with regards to the settings of the context. Only those checks are - * carried out that are specified in the context: - * - Verifies the signature of the TS_TST_INFO. - * - Checks the version number of the response. - * - Check if the requested and returned policies math. - * - Check if the message imprints are the same. - * - Check if the nonces are the same. - * - Check if the TSA name matches the signer. - * - Check if the TSA name is the expected TSA. - */ -static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, - PKCS7 *token, TS_TST_INFO *tst_info) -{ - X509 *signer = NULL; - GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info); - X509_ALGOR *md_alg = NULL; - unsigned char *imprint = NULL; - unsigned imprint_len = 0; - int ret = 0; - int flags = ctx->flags; - - /* Some options require us to also check the signature */ - if (((flags & TS_VFY_SIGNER) && tsa_name != NULL) - || (flags & TS_VFY_TSA_NAME)) { - flags |= TS_VFY_SIGNATURE; - } - - /* Verify the signature. */ - if ((flags & TS_VFY_SIGNATURE) - && !TS_RESP_verify_signature(token, ctx->certs, ctx->store, &signer)) - goto err; - - /* Check version number of response. */ - if ((flags & TS_VFY_VERSION) - && TS_TST_INFO_get_version(tst_info) != 1) { - TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION); - goto err; - } - - /* Check policies. */ - if ((flags & TS_VFY_POLICY) - && !TS_check_policy(ctx->policy, tst_info)) - goto err; - - /* Check message imprints. */ - if ((flags & TS_VFY_IMPRINT) - && !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len, - tst_info)) - goto err; - - /* Compute and check message imprints. */ - if ((flags & TS_VFY_DATA) - && (!TS_compute_imprint(ctx->data, tst_info, - &md_alg, &imprint, &imprint_len) - || !TS_check_imprints(md_alg, imprint, imprint_len, tst_info))) - goto err; - - /* Check nonces. */ - if ((flags & TS_VFY_NONCE) - && !TS_check_nonces(ctx->nonce, tst_info)) - goto err; - - /* Check whether TSA name and signer certificate match. */ - if ((flags & TS_VFY_SIGNER) - && tsa_name && !TS_check_signer_name(tsa_name, signer)) { - TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH); - goto err; - } - - /* Check whether the TSA is the expected one. */ - if ((flags & TS_VFY_TSA_NAME) - && !TS_check_signer_name(ctx->tsa_name, signer)) { - TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED); - goto err; - } - - ret = 1; - err: - X509_free(signer); - X509_ALGOR_free(md_alg); - OPENSSL_free(imprint); - return ret; -} - -static int TS_check_status_info(TS_RESP *response) -{ - TS_STATUS_INFO *info = TS_RESP_get_status_info(response); - long status = ASN1_INTEGER_get(info->status); - const char *status_text = NULL; - char *embedded_status_text = NULL; - char failure_text[TS_STATUS_BUF_SIZE] = ""; - - /* Check if everything went fine. */ - if (status == 0 || status == 1) - return 1; - - /* There was an error, get the description in status_text. */ - if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE) - status_text = TS_status_text[status]; - else - status_text = "unknown code"; - - /* Set the embedded_status_text to the returned description. */ - if (sk_ASN1_UTF8STRING_num(info->text) > 0 - && !(embedded_status_text = TS_get_status_text(info->text))) - return 0; - - /* Filling in failure_text with the failure information. */ - if (info->failure_info) { - int i; - int first = 1; - for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i) { - if (ASN1_BIT_STRING_get_bit(info->failure_info, - TS_failure_info[i].code)) { - if (!first) - strcat(failure_text, ","); - else - first = 0; - strcat(failure_text, TS_failure_info[i].text); - } - } - } - if (failure_text[0] == '\0') - strcpy(failure_text, "unspecified"); - - /* Making up the error string. */ - TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN); - ERR_add_error_data(6, - "status code: ", status_text, - ", status text: ", embedded_status_text ? - embedded_status_text : "unspecified", - ", failure codes: ", failure_text); - OPENSSL_free(embedded_status_text); - - return 0; -} - -static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text) -{ - int i; - int length = 0; - char *result = NULL; - char *p; - - /* Determine length first. */ - for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) { - ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); - if (ASN1_STRING_length(current) > TS_MAX_STATUS_LENGTH - length - 1) - return NULL; - length += ASN1_STRING_length(current); - length += 1; /* separator character */ - } - /* Allocate memory (closing '\0' included). */ - if (!(result = OPENSSL_malloc(length))) { - TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE); - return NULL; - } - /* Concatenate the descriptions. */ - for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i) { - ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); - length = ASN1_STRING_length(current); - if (i > 0) - *p++ = '/'; - strncpy(p, (const char *)ASN1_STRING_data(current), length); - p += length; - } - /* We do have space for this, too. */ - *p = '\0'; - - return result; -} - -static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info) -{ - ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info); - - if (OBJ_cmp(req_oid, resp_oid) != 0) { - TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH); - return 0; - } - - return 1; -} - -static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, - X509_ALGOR **md_alg, - unsigned char **imprint, unsigned *imprint_len) -{ - TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info); - X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint); - const EVP_MD *md; - EVP_MD_CTX md_ctx; - unsigned char buffer[4096]; - int length; - - *md_alg = NULL; - *imprint = NULL; - - /* Return the MD algorithm of the response. */ - if (!(*md_alg = X509_ALGOR_dup(md_alg_resp))) - goto err; - - /* Getting the MD object. */ - if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm))) { - TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM); - goto err; - } - - /* Compute message digest. */ - length = EVP_MD_size(md); - if (length < 0) - goto err; - *imprint_len = length; - if (!(*imprint = OPENSSL_malloc(*imprint_len))) { - TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EVP_DigestInit(&md_ctx, md)) - goto err; - while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) { - if (!EVP_DigestUpdate(&md_ctx, buffer, length)) - goto err; - } - if (!EVP_DigestFinal(&md_ctx, *imprint, NULL)) - goto err; - - return 1; - err: - X509_ALGOR_free(*md_alg); - OPENSSL_free(*imprint); - *imprint_len = 0; - *imprint = 0; - return 0; -} - -static int TS_check_imprints(X509_ALGOR *algor_a, - unsigned char *imprint_a, unsigned len_a, - TS_TST_INFO *tst_info) -{ - TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info); - X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b); - int ret = 0; - - /* algor_a is optional. */ - if (algor_a) { - /* Compare algorithm OIDs. */ - if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm)) - goto err; - - /* The parameter must be NULL in both. */ - if ((algor_a->parameter - && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL) - || (algor_b->parameter - && ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL)) - goto err; - } - - /* Compare octet strings. */ - ret = len_a == (unsigned)ASN1_STRING_length(b->hashed_msg) && - memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0; - err: - if (!ret) - TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH); - return ret; -} - -static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info) -{ - const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info); - - /* Error if nonce is missing. */ - if (!b) { - TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED); - return 0; - } - - /* No error if a nonce is returned without being requested. */ - if (ASN1_INTEGER_cmp(a, b) != 0) { - TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH); - return 0; - } - - return 1; -} - -/* - * Check if the specified TSA name matches either the subject or one of the - * subject alternative names of the TSA certificate. - */ -static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer) -{ - STACK_OF(GENERAL_NAME) *gen_names = NULL; - int idx = -1; - int found = 0; - - /* Check the subject name first. */ - if (tsa_name->type == GEN_DIRNAME - && X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0) - return 1; - - /* Check all the alternative names. */ - gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, NULL, &idx); - while (gen_names != NULL - && !(found = TS_find_name(gen_names, tsa_name) >= 0)) { - /* - * Get the next subject alternative name, although there should be no - * more than one. - */ - GENERAL_NAMES_free(gen_names); - gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, - NULL, &idx); - } - if (gen_names) - GENERAL_NAMES_free(gen_names); - - return found; -} - -/* Returns 1 if name is in gen_names, 0 otherwise. */ -static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name) -{ - int i, found; - for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names); ++i) { - GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i); - found = GENERAL_NAME_cmp(current, name) == 0; - } - return found ? i - 1 : -1; -} |