- 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)
- strcpy(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;
- unsigned 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);
- 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;
+ 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 = response->status_info;
+ long status = ASN1_INTEGER_get(info->status);
+ const char *status_text = NULL;
+ char *embedded_status_text = NULL;
+ char failure_text[TS_STATUS_BUF_SIZE] = "";
+
+ if (status == 0 || status == 1)
+ return 1;
+
+ /* There was an error, get the description in status_text. */
+ if (0 <= status && status < (long) OSSL_NELEM(ts_status_text))
+ status_text = ts_status_text[status];
+ else
+ status_text = "unknown code";
+
+ if (sk_ASN1_UTF8STRING_num(info->text) > 0
+ && (embedded_status_text = ts_get_status_text(info->text)) == NULL)
+ return 0;
+
+ /* Fill in failure_text with the failure information. */
+ if (info->failure_info) {
+ int i;
+ int first = 1;
+ for (i = 0; i < (int)OSSL_NELEM(ts_failure_info); ++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");
+
+ 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;
+ unsigned int length = 0;
+ char *result = NULL;
+ char *p;
+
+ for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) {
+ ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
+ length += ASN1_STRING_length(current);
+ length += 1; /* separator character */
+ }
+ if ((result = OPENSSL_malloc(length)) == NULL) {
+ TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ 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;
+ }
+ *p = '\0';
+
+ return result;
+}
+
+static int ts_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info)
+{
+ ASN1_OBJECT *resp_oid = tst_info->policy_id;
+
+ 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 = tst_info->msg_imprint;
+ X509_ALGOR *md_alg_resp = msg_imprint->hash_algo;
+ const EVP_MD *md;
+ EVP_MD_CTX *md_ctx = NULL;
+ unsigned char buffer[4096];
+ int length;
+
+ *md_alg = NULL;
+ *imprint = NULL;
+
+ if ((*md_alg = X509_ALGOR_dup(md_alg_resp)) == NULL)
+ goto err;
+ if ((md = EVP_get_digestbyobj((*md_alg)->algorithm)) == NULL) {
+ TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM);
+ goto err;
+ }
+ length = EVP_MD_size(md);
+ if (length < 0)
+ goto err;
+ *imprint_len = length;
+ if ((*imprint = OPENSSL_malloc(*imprint_len)) == NULL) {
+ TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ md_ctx = EVP_MD_CTX_new();
+ if (md_ctx == NULL) {
+ 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;
+ EVP_MD_CTX_free(md_ctx);
+
+ return 1;