LCOV - code coverage report
Current view: top level - ts - ts_rsp_sign.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 279 416 67.1 %
Date: 2014-08-02 Functions: 27 35 77.1 %
Branches: 144 302 47.7 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/ts/ts_resp_sign.c */
       2                 :            : /* Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL
       3                 :            :  * project 2002.
       4                 :            :  */
       5                 :            : /* ====================================================================
       6                 :            :  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
       7                 :            :  *
       8                 :            :  * Redistribution and use in source and binary forms, with or without
       9                 :            :  * modification, are permitted provided that the following conditions
      10                 :            :  * are met:
      11                 :            :  *
      12                 :            :  * 1. Redistributions of source code must retain the above copyright
      13                 :            :  *    notice, this list of conditions and the following disclaimer. 
      14                 :            :  *
      15                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      16                 :            :  *    notice, this list of conditions and the following disclaimer in
      17                 :            :  *    the documentation and/or other materials provided with the
      18                 :            :  *    distribution.
      19                 :            :  *
      20                 :            :  * 3. All advertising materials mentioning features or use of this
      21                 :            :  *    software must display the following acknowledgment:
      22                 :            :  *    "This product includes software developed by the OpenSSL Project
      23                 :            :  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
      24                 :            :  *
      25                 :            :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      26                 :            :  *    endorse or promote products derived from this software without
      27                 :            :  *    prior written permission. For written permission, please contact
      28                 :            :  *    licensing@OpenSSL.org.
      29                 :            :  *
      30                 :            :  * 5. Products derived from this software may not be called "OpenSSL"
      31                 :            :  *    nor may "OpenSSL" appear in their names without prior written
      32                 :            :  *    permission of the OpenSSL Project.
      33                 :            :  *
      34                 :            :  * 6. Redistributions of any form whatsoever must retain the following
      35                 :            :  *    acknowledgment:
      36                 :            :  *    "This product includes software developed by the OpenSSL Project
      37                 :            :  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
      38                 :            :  *
      39                 :            :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      40                 :            :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      41                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      42                 :            :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      43                 :            :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      44                 :            :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      45                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      46                 :            :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      47                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      48                 :            :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      49                 :            :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      50                 :            :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      51                 :            :  * ====================================================================
      52                 :            :  *
      53                 :            :  * This product includes cryptographic software written by Eric Young
      54                 :            :  * (eay@cryptsoft.com).  This product includes software written by Tim
      55                 :            :  * Hudson (tjh@cryptsoft.com).
      56                 :            :  *
      57                 :            :  */
      58                 :            : 
      59                 :            : #include "cryptlib.h"
      60                 :            : 
      61                 :            : #if defined(OPENSSL_SYS_UNIX)
      62                 :            : #include <sys/time.h>
      63                 :            : #endif
      64                 :            : 
      65                 :            : #include <openssl/objects.h>
      66                 :            : #include <openssl/ts.h>
      67                 :            : #include <openssl/pkcs7.h>
      68                 :            : 
      69                 :            : /* Private function declarations. */
      70                 :            : 
      71                 :            : static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *);
      72                 :            : static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec);
      73                 :            : static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);
      74                 :            : 
      75                 :            : static void TS_RESP_CTX_init(TS_RESP_CTX *ctx);
      76                 :            : static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx);
      77                 :            : static int TS_RESP_check_request(TS_RESP_CTX *ctx);
      78                 :            : static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx);
      79                 :            : static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, 
      80                 :            :                                             ASN1_OBJECT *policy);
      81                 :            : static int TS_RESP_process_extensions(TS_RESP_CTX *ctx);
      82                 :            : static int TS_RESP_sign(TS_RESP_CTX *ctx);
      83                 :            : 
      84                 :            : static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, 
      85                 :            :                                                    STACK_OF(X509) *certs);
      86                 :            : static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed);
      87                 :            : static int TS_TST_INFO_content_new(PKCS7 *p7);
      88                 :            : static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc);
      89                 :            : 
      90                 :            : static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision(
      91                 :            :         ASN1_GENERALIZEDTIME *, long, long, unsigned);
      92                 :            : 
      93                 :            : /* Default callbacks for response generation. */
      94                 :            : 
      95                 :          0 : static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data)
      96                 :            :         {
      97                 :          0 :         ASN1_INTEGER *serial = ASN1_INTEGER_new();
      98         [ #  # ]:          0 :         if (!serial) goto err;
      99         [ #  # ]:          0 :         if (!ASN1_INTEGER_set(serial, 1)) goto err;
     100                 :            :         return serial;
     101                 :            :  err:
     102                 :          0 :         TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE);
     103                 :          0 :         TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
     104                 :            :                                     "Error during serial number generation.");
     105                 :          0 :         return NULL;
     106                 :            :         }
     107                 :            : 
     108                 :            : #if defined(OPENSSL_SYS_UNIX)
     109                 :            : 
     110                 :            : /* Use the gettimeofday function call. */
     111                 :          3 : static int def_time_cb(struct TS_resp_ctx *ctx, void *data, 
     112                 :            :                        long *sec, long *usec)
     113                 :            :         {
     114                 :            :         struct timeval tv;
     115         [ -  + ]:          3 :         if (gettimeofday(&tv, NULL) != 0) 
     116                 :            :                 {
     117                 :          0 :                 TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
     118                 :          0 :                 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
     119                 :            :                                             "Time is not available.");
     120                 :          0 :                 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
     121                 :          0 :                 return 0;
     122                 :            :                 }
     123                 :            :         /* Return time to caller. */
     124                 :          3 :         *sec = tv.tv_sec;
     125                 :          3 :         *usec = tv.tv_usec;
     126                 :            : 
     127                 :          3 :         return 1;
     128                 :            :         }
     129                 :            : 
     130                 :            : #else
     131                 :            : 
     132                 :            : /* Use the time function call that provides only seconds precision. */
     133                 :            : static int def_time_cb(struct TS_resp_ctx *ctx, void *data, 
     134                 :            :                        long *sec, long *usec)
     135                 :            :         {
     136                 :            :         time_t t;
     137                 :            :         if (time(&t) == (time_t) -1)
     138                 :            :                 {
     139                 :            :                 TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
     140                 :            :                 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
     141                 :            :                                             "Time is not available.");
     142                 :            :                 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
     143                 :            :                 return 0;
     144                 :            :                 }
     145                 :            :         /* Return time to caller, only second precision. */
     146                 :            :         *sec = (long) t;
     147                 :            :         *usec = 0;
     148                 :            : 
     149                 :            :         return 1;
     150                 :            :         }
     151                 :            : 
     152                 :            : #endif
     153                 :            : 
     154                 :          0 : static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext,
     155                 :            :                             void *data)
     156                 :            :         {
     157                 :            :         /* No extensions are processed here. */
     158                 :          0 :         TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
     159                 :            :                                     "Unsupported extension.");
     160                 :          0 :         TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION);
     161                 :          0 :         return 0;
     162                 :            :         }
     163                 :            : 
     164                 :            : /* TS_RESP_CTX management functions. */
     165                 :            : 
     166                 :          3 : TS_RESP_CTX *TS_RESP_CTX_new()
     167                 :            :         {
     168                 :            :         TS_RESP_CTX *ctx;
     169                 :            : 
     170         [ -  + ]:          3 :         if (!(ctx = (TS_RESP_CTX *) OPENSSL_malloc(sizeof(TS_RESP_CTX))))
     171                 :            :                 {
     172                 :          0 :                 TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE);
     173                 :          0 :                 return NULL;
     174                 :            :                 }
     175                 :            :         memset(ctx, 0, sizeof(TS_RESP_CTX));
     176                 :            : 
     177                 :            :         /* Setting default callbacks. */
     178                 :          3 :         ctx->serial_cb = def_serial_cb;
     179                 :          3 :         ctx->time_cb = def_time_cb;
     180                 :          3 :         ctx->extension_cb = def_extension_cb;
     181                 :            : 
     182                 :          3 :         return ctx;
     183                 :            :         }
     184                 :            : 
     185                 :          3 : void TS_RESP_CTX_free(TS_RESP_CTX *ctx)
     186                 :            :         {
     187         [ +  - ]:          3 :         if (!ctx) return;
     188                 :            : 
     189                 :          3 :         X509_free(ctx->signer_cert);
     190                 :          3 :         EVP_PKEY_free(ctx->signer_key);
     191                 :          3 :         sk_X509_pop_free(ctx->certs, X509_free);
     192                 :          3 :         sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free);
     193                 :          3 :         ASN1_OBJECT_free(ctx->default_policy);
     194                 :          3 :         sk_EVP_MD_free(ctx->mds);    /* No EVP_MD_free method exists. */
     195                 :          3 :         ASN1_INTEGER_free(ctx->seconds);
     196                 :          3 :         ASN1_INTEGER_free(ctx->millis);
     197                 :          3 :         ASN1_INTEGER_free(ctx->micros);
     198                 :          3 :         OPENSSL_free(ctx);
     199                 :            :         }
     200                 :            : 
     201                 :          3 : int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)
     202                 :            :         {
     203         [ -  + ]:          3 :         if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1)
     204                 :            :                 {
     205                 :          0 :                 TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT, 
     206                 :            :                       TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
     207                 :          0 :                 return 0;
     208                 :            :                 }
     209         [ -  + ]:          3 :         if (ctx->signer_cert) X509_free(ctx->signer_cert);
     210                 :          3 :         ctx->signer_cert = signer;
     211                 :          3 :         CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509);
     212                 :          3 :         return 1;
     213                 :            :         }
     214                 :            : 
     215                 :          3 : int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)
     216                 :            :         {
     217         [ -  + ]:          3 :         if (ctx->signer_key) EVP_PKEY_free(ctx->signer_key);
     218                 :          3 :         ctx->signer_key = key;
     219                 :          3 :         CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY);
     220                 :            : 
     221                 :          3 :         return 1;
     222                 :            :         }
     223                 :            : 
     224                 :          3 : int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy)
     225                 :            :         {
     226         [ -  + ]:          3 :         if (ctx->default_policy) ASN1_OBJECT_free(ctx->default_policy);
     227         [ -  + ]:          3 :         if (!(ctx->default_policy = OBJ_dup(def_policy))) goto err;
     228                 :            :         return 1;
     229                 :            :  err:
     230                 :          0 :         TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE);
     231                 :          0 :         return 0;
     232                 :            :         }
     233                 :            : 
     234                 :          3 : int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs)
     235                 :            :         {
     236                 :            : 
     237         [ -  + ]:          3 :         if (ctx->certs)
     238                 :            :                 {
     239                 :          0 :                 sk_X509_pop_free(ctx->certs, X509_free);
     240                 :          0 :                 ctx->certs = NULL;
     241                 :            :                 }
     242         [ +  - ]:          3 :         if (!certs) return 1;
     243         [ -  + ]:          3 :         if (!(ctx->certs = X509_chain_up_ref(certs))) 
     244                 :            :                 {
     245                 :          0 :                 TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE);
     246                 :          0 :                 return 0;
     247                 :            :                 }
     248                 :            : 
     249                 :            :         return 1;
     250                 :            :         }
     251                 :            : 
     252                 :          6 : int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy)
     253                 :            :         {
     254                 :          6 :         ASN1_OBJECT *copy = NULL;
     255                 :            : 
     256                 :            :         /* Create new policy stack if necessary. */
     257 [ +  + ][ +  - ]:          6 :         if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null())) 
     258                 :            :                 goto err;
     259         [ +  - ]:          6 :         if (!(copy = OBJ_dup(policy))) goto err;
     260         [ -  + ]:          6 :         if (!sk_ASN1_OBJECT_push(ctx->policies, copy)) goto err;
     261                 :            : 
     262                 :            :         return 1;
     263                 :            :  err:
     264                 :          0 :         TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE);
     265                 :          0 :         ASN1_OBJECT_free(copy);
     266                 :          0 :         return 0;
     267                 :            :         }
     268                 :            : 
     269                 :          6 : int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md)
     270                 :            :         {
     271                 :            :         /* Create new md stack if necessary. */
     272 [ +  + ][ +  - ]:          6 :         if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null())) 
     273                 :            :                 goto err;
     274                 :            :         /* Add the shared md, no copy needed. */
     275         [ -  + ]:          6 :         if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md)) goto err;
     276                 :            : 
     277                 :            :         return 1;
     278                 :            :  err:
     279                 :          0 :         TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE);
     280                 :          0 :         return 0;
     281                 :            :         }
     282                 :            : 
     283                 :            : #define TS_RESP_CTX_accuracy_free(ctx)          \
     284                 :            :         ASN1_INTEGER_free(ctx->seconds);     \
     285                 :            :         ctx->seconds = NULL;                 \
     286                 :            :         ASN1_INTEGER_free(ctx->millis);              \
     287                 :            :         ctx->millis = NULL;                  \
     288                 :            :         ASN1_INTEGER_free(ctx->micros);              \
     289                 :            :         ctx->micros = NULL;
     290                 :            : 
     291                 :          3 : int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, 
     292                 :            :                              int secs, int millis, int micros)
     293                 :            :         {
     294                 :            : 
     295                 :          3 :         TS_RESP_CTX_accuracy_free(ctx);
     296 [ +  - ][ +  - ]:          3 :         if (secs && (!(ctx->seconds = ASN1_INTEGER_new())
     297         [ +  - ]:          3 :                      || !ASN1_INTEGER_set(ctx->seconds, secs)))
     298                 :            :                 goto err;
     299 [ +  - ][ +  - ]:          3 :         if (millis && (!(ctx->millis = ASN1_INTEGER_new())
     300         [ +  - ]:          3 :                        || !ASN1_INTEGER_set(ctx->millis, millis)))
     301                 :            :                 goto err;
     302 [ +  - ][ +  - ]:          3 :         if (micros && (!(ctx->micros = ASN1_INTEGER_new())
     303         [ -  + ]:          3 :                        || !ASN1_INTEGER_set(ctx->micros, micros)))
     304                 :            :                 goto err;
     305                 :            : 
     306                 :            :         return 1;
     307                 :            :  err:
     308                 :          0 :         TS_RESP_CTX_accuracy_free(ctx);
     309                 :          0 :         TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
     310                 :          0 :         return 0;
     311                 :            :         }
     312                 :            : 
     313                 :          9 : void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags)
     314                 :            :         {
     315                 :          9 :         ctx->flags |= flags;
     316                 :          9 :         }
     317                 :            : 
     318                 :          3 : void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data)
     319                 :            :         {
     320                 :          3 :         ctx->serial_cb = cb;
     321                 :          3 :         ctx->serial_cb_data = data;
     322                 :          3 :         }
     323                 :            : 
     324                 :          0 : void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data)
     325                 :            :         {
     326                 :          0 :         ctx->time_cb = cb;
     327                 :          0 :         ctx->time_cb_data = data;
     328                 :          0 :         }
     329                 :            : 
     330                 :          0 : void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, 
     331                 :            :                                   TS_extension_cb cb, void *data)
     332                 :            :         {
     333                 :          0 :         ctx->extension_cb = cb;
     334                 :          0 :         ctx->extension_cb_data = data;
     335                 :          0 :         }
     336                 :            : 
     337                 :          3 : int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, 
     338                 :            :                                 int status, const char *text)
     339                 :            :         {
     340                 :          3 :         TS_STATUS_INFO *si = NULL;
     341                 :          3 :         ASN1_UTF8STRING *utf8_text = NULL;
     342                 :          3 :         int ret = 0;
     343                 :            : 
     344         [ +  - ]:          3 :         if (!(si = TS_STATUS_INFO_new())) goto err;
     345         [ +  - ]:          3 :         if (!ASN1_INTEGER_set(si->status, status)) goto err;
     346         [ -  + ]:          3 :         if (text)
     347                 :            :                 {
     348         [ #  # ]:          0 :                 if (!(utf8_text = ASN1_UTF8STRING_new())
     349         [ #  # ]:          0 :                     || !ASN1_STRING_set(utf8_text, text, strlen(text)))
     350                 :            :                         goto err;
     351 [ #  # ][ #  # ]:          0 :                 if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null()))
     352                 :            :                         goto err;
     353         [ #  # ]:          0 :                 if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text)) goto err;
     354                 :            :                 utf8_text = NULL;       /* Ownership is lost. */
     355                 :            :                 }
     356         [ +  - ]:          3 :         if (!TS_RESP_set_status_info(ctx->response, si)) goto err;
     357                 :          3 :         ret = 1;
     358                 :            :  err:
     359         [ -  + ]:          3 :         if (!ret)
     360                 :          0 :                 TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
     361                 :          3 :         TS_STATUS_INFO_free(si);
     362                 :          3 :         ASN1_UTF8STRING_free(utf8_text);
     363                 :          3 :         return ret;
     364                 :            :         }
     365                 :            : 
     366                 :          0 : int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, 
     367                 :            :                                      int status, const char *text)
     368                 :            :         {
     369                 :          0 :         int ret = 1;
     370                 :          0 :         TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);
     371                 :            : 
     372         [ #  # ]:          0 :         if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED)
     373                 :            :                 {
     374                 :            :                 /* Status has not been set, set it now. */
     375                 :          0 :                 ret = TS_RESP_CTX_set_status_info(ctx, status, text);
     376                 :            :                 }
     377                 :          0 :         return ret;
     378                 :            :         }
     379                 :            : 
     380                 :          0 : int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure)
     381                 :            :         {
     382                 :          0 :         TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response);
     383 [ #  # ][ #  # ]:          0 :         if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new()))
     384                 :            :                 goto err;
     385         [ #  # ]:          0 :         if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1))
     386                 :            :                 goto err;
     387                 :            :         return 1;
     388                 :            :  err:
     389                 :          0 :         TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE);
     390                 :          0 :         return 0;
     391                 :            :         }
     392                 :            : 
     393                 :          0 : TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx)
     394                 :            :         {
     395                 :          0 :         return ctx->request;
     396                 :            :         }
     397                 :            : 
     398                 :          0 : TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx)
     399                 :            :         {
     400                 :          0 :         return ctx->tst_info;
     401                 :            :         }
     402                 :            : 
     403                 :          3 : int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, unsigned precision)
     404                 :            :        {
     405         [ +  - ]:          3 :        if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
     406                 :            :                return 0;
     407                 :          3 :        ctx->clock_precision_digits = precision;
     408                 :          3 :        return 1;
     409                 :            :        }
     410                 :            : 
     411                 :            : /* Main entry method of the response generation. */
     412                 :          3 : TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
     413                 :            :         {
     414                 :            :         ASN1_OBJECT *policy;
     415                 :            :         TS_RESP *response;
     416                 :          3 :         int result = 0;
     417                 :            : 
     418                 :          3 :         TS_RESP_CTX_init(ctx);
     419                 :            : 
     420                 :            :         /* Creating the response object. */
     421         [ -  + ]:          3 :         if (!(ctx->response = TS_RESP_new())) 
     422                 :            :                 {
     423                 :          0 :                 TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE);
     424                 :          0 :                 goto end;
     425                 :            :                 }
     426                 :            : 
     427                 :            :         /* Parsing DER request. */
     428         [ -  + ]:          3 :         if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL)))
     429                 :            :                 {
     430                 :          0 :                 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
     431                 :            :                                             "Bad request format or "
     432                 :            :                                             "system error.");
     433                 :          0 :                 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
     434                 :          0 :                 goto end;
     435                 :            :                 }
     436                 :            : 
     437                 :            :         /* Setting default status info. */
     438         [ +  - ]:          3 :         if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL))
     439                 :            :                 goto end;
     440                 :            : 
     441                 :            :         /* Checking the request format. */
     442         [ +  - ]:          3 :         if (!TS_RESP_check_request(ctx)) goto end;
     443                 :            : 
     444                 :            :         /* Checking acceptable policies. */
     445         [ +  - ]:          3 :         if (!(policy = TS_RESP_get_policy(ctx))) goto end;
     446                 :            : 
     447                 :            :         /* Creating the TS_TST_INFO object. */
     448         [ +  - ]:          3 :         if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy)))
     449                 :            :                 goto end;
     450                 :            : 
     451                 :            :         /* Processing extensions. */
     452         [ +  - ]:          3 :         if (!TS_RESP_process_extensions(ctx)) goto end;
     453                 :            : 
     454                 :            :         /* Generating the signature. */
     455         [ +  - ]:          3 :         if (!TS_RESP_sign(ctx)) goto end;
     456                 :            : 
     457                 :            :         /* Everything was successful. */
     458                 :          3 :         result = 1;
     459                 :            :  end:
     460         [ -  + ]:          3 :         if (!result)
     461                 :            :                 {
     462                 :          0 :                 TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR);
     463         [ #  # ]:          0 :                 if (ctx->response != NULL)
     464                 :            :                         {
     465         [ #  # ]:          0 :                         if (TS_RESP_CTX_set_status_info_cond(ctx,
     466                 :            :                                 TS_STATUS_REJECTION, "Error during response "
     467                 :            :                                 "generation.") == 0)
     468                 :            :                                 {
     469                 :          0 :                                 TS_RESP_free(ctx->response);
     470                 :          0 :                                 ctx->response = NULL;
     471                 :            :                                 }
     472                 :            :                         }
     473                 :            :                 }
     474                 :          3 :         response = ctx->response;
     475                 :          3 :         ctx->response = NULL;        /* Ownership will be returned to caller. */
     476                 :          3 :         TS_RESP_CTX_cleanup(ctx);
     477                 :          3 :         return response;
     478                 :            :         }
     479                 :            : 
     480                 :            : /* Initializes the variable part of the context. */
     481                 :          3 : static void TS_RESP_CTX_init(TS_RESP_CTX *ctx)
     482                 :            :         {
     483                 :          3 :         ctx->request = NULL;
     484                 :          3 :         ctx->response = NULL;
     485                 :          3 :         ctx->tst_info = NULL;
     486                 :          3 :         }
     487                 :            : 
     488                 :            : /* Cleans up the variable part of the context. */
     489                 :          3 : static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx)
     490                 :            :         {
     491                 :          3 :         TS_REQ_free(ctx->request);
     492                 :          3 :         ctx->request = NULL;
     493                 :          3 :         TS_RESP_free(ctx->response);
     494                 :          3 :         ctx->response = NULL;
     495                 :          3 :         TS_TST_INFO_free(ctx->tst_info);
     496                 :          3 :         ctx->tst_info = NULL;
     497                 :          3 :         }
     498                 :            : 
     499                 :            : /* Checks the format and content of the request. */
     500                 :          3 : static int TS_RESP_check_request(TS_RESP_CTX *ctx)
     501                 :            :         {
     502                 :          3 :         TS_REQ *request = ctx->request;
     503                 :            :         TS_MSG_IMPRINT *msg_imprint;
     504                 :            :         X509_ALGOR *md_alg;
     505                 :            :         int md_alg_id;
     506                 :            :         const ASN1_OCTET_STRING *digest;
     507                 :          3 :         EVP_MD *md = NULL;
     508                 :            :         int i;
     509                 :            : 
     510                 :            :         /* Checking request version. */
     511         [ -  + ]:          3 :         if (TS_REQ_get_version(request) != 1)
     512                 :            :                 {
     513                 :          0 :                 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
     514                 :            :                                             "Bad request version.");
     515                 :          0 :                 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST);
     516                 :          0 :                 return 0;
     517                 :            :                 }
     518                 :            : 
     519                 :            :         /* Checking message digest algorithm. */
     520                 :          3 :         msg_imprint = TS_REQ_get_msg_imprint(request);
     521                 :          3 :         md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint);
     522                 :          3 :         md_alg_id = OBJ_obj2nid(md_alg->algorithm);
     523 [ +  + ][ +  - ]:          9 :         for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i)
     524                 :            :                 {
     525                 :          6 :                 EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i);
     526         [ +  + ]:          6 :                 if (md_alg_id == EVP_MD_type(current_md))
     527                 :          3 :                         md = current_md;
     528                 :            :                 }
     529         [ -  + ]:          3 :         if (!md)
     530                 :            :                 {
     531                 :          0 :                 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
     532                 :            :                                             "Message digest algorithm is "
     533                 :            :                                             "not supported.");
     534                 :          0 :                 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
     535                 :          0 :                 return 0;
     536                 :            :                 }
     537                 :            : 
     538                 :            :         /* No message digest takes parameter. */
     539         [ +  - ]:          3 :         if (md_alg->parameter 
     540         [ -  + ]:          3 :             && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL)
     541                 :            :                 {
     542                 :          0 :                 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
     543                 :            :                                             "Superfluous message digest "
     544                 :            :                                             "parameter.");
     545                 :          0 :                 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
     546                 :          0 :                 return 0;
     547                 :            :                 }
     548                 :            :         /* Checking message digest size. */
     549                 :          3 :         digest = TS_MSG_IMPRINT_get_msg(msg_imprint);
     550         [ -  + ]:          3 :         if (digest->length != EVP_MD_size(md))
     551                 :            :                 {
     552                 :          0 :                 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
     553                 :            :                                             "Bad message digest.");
     554                 :          0 :                 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
     555                 :          0 :                 return 0;
     556                 :            :                 }
     557                 :            : 
     558                 :            :         return 1;
     559                 :            :         }
     560                 :            : 
     561                 :            : /* Returns the TSA policy based on the requested and acceptable policies. */
     562                 :          3 : static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx)
     563                 :            :         {
     564                 :          3 :         ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request);
     565                 :          3 :         ASN1_OBJECT *policy = NULL;
     566                 :            :         int i;
     567                 :            : 
     568         [ -  + ]:          3 :         if (ctx->default_policy == NULL)
     569                 :            :                 {
     570                 :          0 :                 TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER);
     571                 :          0 :                 return NULL;
     572                 :            :                 }
     573                 :            :         /* Return the default policy if none is requested or the default is
     574                 :            :            requested. */
     575 [ +  - ][ +  + ]:          3 :         if (!requested || !OBJ_cmp(requested, ctx->default_policy))
     576                 :          3 :                 policy = ctx->default_policy;
     577                 :            : 
     578                 :            :         /* Check if the policy is acceptable. */
     579 [ +  + ][ +  - ]:          5 :         for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i)
     580                 :            :                 {
     581                 :          2 :                 ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i);
     582         [ +  - ]:          2 :                 if (!OBJ_cmp(requested, current))
     583                 :          2 :                         policy = current;
     584                 :            :                 }
     585         [ -  + ]:          3 :         if (!policy)
     586                 :            :                 {
     587                 :          0 :                 TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY);
     588                 :          0 :                 TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
     589                 :            :                                             "Requested policy is not "
     590                 :            :                                             "supported.");
     591                 :          0 :                 TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY);
     592                 :            :                 }
     593                 :          3 :         return policy;
     594                 :            :         }
     595                 :            : 
     596                 :            : /* Creates the TS_TST_INFO object based on the settings of the context. */
     597                 :          3 : static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx,
     598                 :            :                                             ASN1_OBJECT *policy)
     599                 :            :         {
     600                 :          3 :         int result = 0;
     601                 :          3 :         TS_TST_INFO *tst_info = NULL;
     602                 :          3 :         ASN1_INTEGER *serial = NULL;
     603                 :          3 :         ASN1_GENERALIZEDTIME *asn1_time = NULL;
     604                 :            :         long sec, usec;
     605                 :          3 :         TS_ACCURACY *accuracy = NULL;
     606                 :            :         const ASN1_INTEGER *nonce;
     607                 :          3 :         GENERAL_NAME *tsa_name = NULL;
     608                 :            : 
     609         [ +  - ]:          3 :         if (!(tst_info = TS_TST_INFO_new())) goto end;
     610         [ +  - ]:          3 :         if (!TS_TST_INFO_set_version(tst_info, 1)) goto end;
     611         [ +  - ]:          3 :         if (!TS_TST_INFO_set_policy_id(tst_info, policy)) goto end;
     612         [ +  - ]:          3 :         if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint))
     613                 :            :                 goto end;
     614         [ +  - ]:          3 :         if (!(serial = (*ctx->serial_cb)(ctx, ctx->serial_cb_data))
     615         [ +  - ]:          3 :             || !TS_TST_INFO_set_serial(tst_info, serial))
     616                 :            :                 goto end;
     617         [ +  - ]:          3 :         if (!(*ctx->time_cb)(ctx, ctx->time_cb_data, &sec, &usec)
     618         [ +  - ]:          3 :             || !(asn1_time = TS_RESP_set_genTime_with_precision(NULL, 
     619                 :            :                                         sec, usec, 
     620                 :            :                                         ctx->clock_precision_digits))
     621         [ +  - ]:          3 :             || !TS_TST_INFO_set_time(tst_info, asn1_time))
     622                 :            :                 goto end;
     623                 :            : 
     624                 :            :         /* Setting accuracy if needed. */
     625 [ -  + ][ #  # ]:          3 :         if ((ctx->seconds || ctx->millis || ctx->micros) 
                 [ #  # ]
     626         [ +  - ]:          3 :             && !(accuracy = TS_ACCURACY_new()))
     627                 :            :                 goto end;
     628                 :            : 
     629 [ +  - ][ +  - ]:          3 :         if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds))
     630                 :            :                 goto end;
     631 [ +  - ][ +  - ]:          3 :         if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis))
     632                 :            :                 goto end;
     633 [ +  - ][ +  - ]:          3 :         if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros))
     634                 :            :                 goto end;
     635 [ +  - ][ +  - ]:          3 :         if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy)) 
     636                 :            :                 goto end;
     637                 :            : 
     638                 :            :         /* Setting ordering. */
     639         [ +  - ]:          3 :         if ((ctx->flags & TS_ORDERING) 
     640         [ +  - ]:          3 :             && !TS_TST_INFO_set_ordering(tst_info, 1))
     641                 :            :                 goto end;
     642                 :            :         
     643                 :            :         /* Setting nonce if needed. */
     644         [ +  + ]:          3 :         if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL
     645         [ +  - ]:          1 :             && !TS_TST_INFO_set_nonce(tst_info, nonce))
     646                 :            :                 goto end;
     647                 :            : 
     648                 :            :         /* Setting TSA name to subject of signer certificate. */
     649         [ +  - ]:          3 :         if (ctx->flags & TS_TSA_NAME)
     650                 :            :                 {
     651         [ +  - ]:          3 :                 if (!(tsa_name = GENERAL_NAME_new())) goto end;
     652                 :          3 :                 tsa_name->type = GEN_DIRNAME;
     653                 :          3 :                 tsa_name->d.dirn = 
     654                 :          3 :                         X509_NAME_dup(ctx->signer_cert->cert_info->subject);
     655         [ +  - ]:          3 :                 if (!tsa_name->d.dirn) goto end;
     656         [ +  - ]:          3 :                 if (!TS_TST_INFO_set_tsa(tst_info, tsa_name)) goto end;
     657                 :            :                 }
     658                 :            : 
     659                 :            :         result = 1;
     660                 :            :  end:
     661         [ -  + ]:          3 :         if (!result)
     662                 :            :                 {
     663                 :          0 :                 TS_TST_INFO_free(tst_info);
     664                 :          0 :                 tst_info = NULL;
     665                 :          0 :                 TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR);
     666                 :          0 :                 TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
     667                 :            :                                                  "Error during TSTInfo "
     668                 :            :                                                  "generation.");
     669                 :            :                 }
     670                 :          3 :         GENERAL_NAME_free(tsa_name);
     671                 :          3 :         TS_ACCURACY_free(accuracy);
     672                 :          3 :         ASN1_GENERALIZEDTIME_free(asn1_time);
     673                 :          3 :         ASN1_INTEGER_free(serial);
     674                 :            :         
     675                 :          3 :         return tst_info;
     676                 :            :         }
     677                 :            : 
     678                 :            : /* Processing the extensions of the request. */
     679                 :          3 : static int TS_RESP_process_extensions(TS_RESP_CTX *ctx)
     680                 :            :         {
     681                 :          3 :         STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request);
     682                 :            :         int i;
     683                 :          3 :         int ok = 1;
     684                 :            : 
     685 [ +  - ][ -  + ]:          3 :         for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i)
     686                 :            :                 {
     687                 :          0 :                 X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
     688                 :            :                 /* XXXXX The last argument was previously
     689                 :            :                    (void *)ctx->extension_cb, but ISO C doesn't permit
     690                 :            :                    converting a function pointer to void *.  For lack of
     691                 :            :                    better information, I'm placing a NULL there instead.
     692                 :            :                    The callback can pick its own address out from the ctx
     693                 :            :                    anyway...
     694                 :            :                 */
     695                 :          0 :                 ok = (*ctx->extension_cb)(ctx, ext, NULL);
     696                 :            :                 }
     697                 :            : 
     698                 :          3 :         return ok;
     699                 :            :         }
     700                 :            : 
     701                 :            : /* Functions for signing the TS_TST_INFO structure of the context. */
     702                 :          3 : static int TS_RESP_sign(TS_RESP_CTX *ctx)
     703                 :            :         {
     704                 :          3 :         int ret = 0;
     705                 :          3 :         PKCS7 *p7 = NULL;
     706                 :            :         PKCS7_SIGNER_INFO *si;
     707                 :            :         STACK_OF(X509) *certs;  /* Certificates to include in sc. */
     708                 :          3 :         ESS_SIGNING_CERT *sc = NULL;
     709                 :            :         ASN1_OBJECT *oid;
     710                 :          3 :         BIO *p7bio = NULL;
     711                 :            :         int i;
     712                 :            : 
     713                 :            :         /* Check if signcert and pkey match. */
     714         [ -  + ]:          3 :         if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) {
     715                 :          0 :                 TSerr(TS_F_TS_RESP_SIGN, 
     716                 :            :                       TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
     717                 :          0 :                 goto err;
     718                 :            :         }
     719                 :            : 
     720                 :            :         /* Create a new PKCS7 signed object. */
     721         [ -  + ]:          3 :         if (!(p7 = PKCS7_new())) {
     722                 :          0 :                 TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
     723                 :          0 :                 goto err;
     724                 :            :         }
     725         [ +  - ]:          3 :         if (!PKCS7_set_type(p7, NID_pkcs7_signed)) goto err;
     726                 :            : 
     727                 :            :         /* Force SignedData version to be 3 instead of the default 1. */
     728         [ +  - ]:          3 :         if (!ASN1_INTEGER_set(p7->d.sign->version, 3)) goto err;
     729                 :            : 
     730                 :            :         /* Add signer certificate and optional certificate chain. */
     731         [ +  + ]:          3 :         if (TS_REQ_get_cert_req(ctx->request))
     732                 :            :                 {
     733                 :          1 :                 PKCS7_add_certificate(p7, ctx->signer_cert);
     734         [ +  - ]:          1 :                 if (ctx->certs)
     735                 :            :                         {
     736         [ +  + ]:          2 :                         for(i = 0; i < sk_X509_num(ctx->certs); ++i) 
     737                 :            :                                 {
     738                 :          1 :                                 X509 *cert = sk_X509_value(ctx->certs, i);
     739                 :          1 :                                 PKCS7_add_certificate(p7, cert);
     740                 :            :                                 }
     741                 :            :                         }
     742                 :            :                 }
     743                 :            : 
     744                 :            :         /* Add a new signer info. */
     745         [ -  + ]:          3 :         if (!(si = PKCS7_add_signature(p7, ctx->signer_cert, 
     746                 :            :                                        ctx->signer_key, EVP_sha1())))
     747                 :            :                 {
     748                 :          0 :                 TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR);
     749                 :          0 :                 goto err;
     750                 :            :                 }
     751                 :            : 
     752                 :            :         /* Add content type signed attribute to the signer info. */
     753                 :          3 :         oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
     754         [ -  + ]:          3 :         if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
     755                 :            :                                         V_ASN1_OBJECT, oid))
     756                 :            :                 {
     757                 :          0 :                 TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR);
     758                 :          0 :                 goto err;
     759                 :            :                 }
     760                 :            : 
     761                 :            :         /* Create the ESS SigningCertificate attribute which contains 
     762                 :            :            the signer certificate id and optionally the certificate chain. */
     763         [ +  - ]:          3 :         certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;
     764         [ +  - ]:          3 :         if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs)))
     765                 :            :                 goto err;
     766                 :            : 
     767                 :            :         /* Add SigningCertificate signed attribute to the signer info. */
     768         [ -  + ]:          3 :         if (!ESS_add_signing_cert(si, sc))
     769                 :            :                 {
     770                 :          0 :                 TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
     771                 :          0 :                 goto err;
     772                 :            :                 }       
     773                 :            : 
     774                 :            :         /* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */
     775         [ +  - ]:          3 :         if (!TS_TST_INFO_content_new(p7)) goto err;
     776                 :            : 
     777                 :            :         /* Add the DER encoded tst_info to the PKCS7 structure. */
     778         [ -  + ]:          3 :         if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
     779                 :          0 :                 TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
     780                 :          0 :                 goto err;
     781                 :            :         }
     782                 :            : 
     783                 :            :         /* Convert tst_info to DER. */
     784         [ -  + ]:          3 :         if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info))
     785                 :            :                 {
     786                 :          0 :                 TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
     787                 :          0 :                 goto err;
     788                 :            :                 }
     789                 :            : 
     790                 :            :         /* Create the signature and add it to the signer info. */
     791         [ -  + ]:          3 :         if (!PKCS7_dataFinal(p7, p7bio))
     792                 :            :                 {
     793                 :          0 :                 TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
     794                 :          0 :                 goto err;
     795                 :            :                 }
     796                 :            : 
     797                 :            :         /* Set new PKCS7 and TST_INFO objects. */
     798                 :          3 :         TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info);
     799                 :          3 :         p7 = NULL;              /* Ownership is lost. */
     800                 :          3 :         ctx->tst_info = NULL;        /* Ownership is lost. */
     801                 :            : 
     802                 :          3 :         ret = 1;
     803                 :            :  err:
     804         [ -  + ]:          3 :         if (!ret)
     805                 :          0 :                 TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
     806                 :            :                                                  "Error during signature "
     807                 :            :                                                  "generation.");
     808                 :          3 :         BIO_free_all(p7bio);
     809                 :          3 :         ESS_SIGNING_CERT_free(sc);
     810                 :          3 :         PKCS7_free(p7);
     811                 :          3 :         return ret;
     812                 :            :         }
     813                 :            : 
     814                 :          3 : static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, 
     815                 :            :                                                    STACK_OF(X509) *certs)
     816                 :            :         {
     817                 :            :         ESS_CERT_ID *cid;
     818                 :          3 :         ESS_SIGNING_CERT *sc = NULL;
     819                 :            :         int i;
     820                 :            : 
     821                 :            :         /* Creating the ESS_CERT_ID stack. */
     822         [ +  - ]:          3 :         if (!(sc = ESS_SIGNING_CERT_new())) goto err;
     823 [ -  + ][ #  # ]:          3 :         if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null()))
     824                 :            :                 goto err;
     825                 :            : 
     826                 :            :         /* Adding the signing certificate id. */
     827         [ +  - ]:          3 :         if (!(cid = ESS_CERT_ID_new_init(signcert, 0))
     828         [ +  - ]:          3 :             || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
     829                 :            :                 goto err;
     830                 :            :         /* Adding the certificate chain ids. */
     831         [ +  + ]:          6 :         for (i = 0; i < sk_X509_num(certs); ++i)
     832                 :            :                 {
     833                 :          3 :                 X509 *cert = sk_X509_value(certs, i);
     834         [ +  - ]:          3 :                 if (!(cid = ESS_CERT_ID_new_init(cert, 1))
     835         [ +  - ]:          3 :                     || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
     836                 :            :                         goto err;
     837                 :            :                 }
     838                 :            : 
     839                 :            :         return sc;
     840                 :            : err:
     841                 :          0 :         ESS_SIGNING_CERT_free(sc);
     842                 :          0 :         TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE);
     843                 :          0 :         return NULL;
     844                 :            :         }
     845                 :            : 
     846                 :          6 : static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed)
     847                 :            :         {
     848                 :          6 :         ESS_CERT_ID *cid = NULL;
     849                 :          6 :         GENERAL_NAME *name = NULL;
     850                 :            :         
     851                 :            :         /* Recompute SHA1 hash of certificate if necessary (side effect). */
     852                 :          6 :         X509_check_purpose(cert, -1, 0);
     853                 :            : 
     854         [ +  - ]:          6 :         if (!(cid = ESS_CERT_ID_new())) goto err;
     855         [ +  - ]:          6 :         if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash,
     856                 :            :                                    sizeof(cert->sha1_hash)))
     857                 :            :                 goto err;
     858                 :            : 
     859                 :            :         /* Setting the issuer/serial if requested. */
     860         [ +  + ]:          6 :         if (issuer_needed)
     861                 :            :                 {
     862                 :            :                 /* Creating issuer/serial structure. */
     863         [ +  - ]:          3 :                 if (!cid->issuer_serial
     864         [ +  - ]:          3 :                     && !(cid->issuer_serial = ESS_ISSUER_SERIAL_new()))
     865                 :            :                         goto err;
     866                 :            :                 /* Creating general name from the certificate issuer. */
     867         [ +  - ]:          3 :                 if (!(name = GENERAL_NAME_new())) goto err;
     868                 :          3 :                 name->type = GEN_DIRNAME;
     869         [ +  - ]:          3 :                 if (!(name->d.dirn = X509_NAME_dup(cert->cert_info->issuer))) 
     870                 :            :                         goto err;
     871         [ +  - ]:          3 :                 if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) 
     872                 :            :                         goto err;
     873                 :          3 :                 name = NULL;    /* Ownership is lost. */
     874                 :            :                 /* Setting the serial number. */
     875                 :          3 :                 ASN1_INTEGER_free(cid->issuer_serial->serial);
     876         [ +  - ]:          3 :                 if (!(cid->issuer_serial->serial = 
     877                 :          3 :                       ASN1_INTEGER_dup(cert->cert_info->serialNumber)))
     878                 :            :                         goto err;
     879                 :            :                 }
     880                 :            : 
     881                 :          6 :         return cid;
     882                 :            : err:
     883                 :          0 :         GENERAL_NAME_free(name);
     884                 :          0 :         ESS_CERT_ID_free(cid);
     885                 :          0 :         TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE);
     886                 :          0 :         return NULL;
     887                 :            :         }
     888                 :            : 
     889                 :          3 : static int TS_TST_INFO_content_new(PKCS7 *p7)
     890                 :            :         {
     891                 :          3 :         PKCS7 *ret = NULL;
     892                 :          3 :         ASN1_OCTET_STRING *octet_string = NULL;
     893                 :            : 
     894                 :            :         /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */
     895         [ +  - ]:          3 :         if (!(ret = PKCS7_new())) goto err;
     896         [ +  - ]:          3 :         if (!(ret->d.other = ASN1_TYPE_new())) goto err;
     897                 :          3 :         ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
     898         [ +  - ]:          3 :         if (!(octet_string = ASN1_OCTET_STRING_new())) goto err;
     899                 :          3 :         ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string);
     900                 :          3 :         octet_string = NULL;
     901                 :            : 
     902                 :            :         /* Add encapsulated content to signed PKCS7 structure. */
     903         [ -  + ]:          3 :         if (!PKCS7_set_content(p7, ret)) goto err;
     904                 :            : 
     905                 :            :         return 1;
     906                 :            :  err:
     907                 :          0 :         ASN1_OCTET_STRING_free(octet_string);
     908                 :          0 :         PKCS7_free(ret);
     909                 :          0 :         return 0;
     910                 :            :         }
     911                 :            : 
     912                 :          3 : static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc)
     913                 :            :         {
     914                 :          3 :         ASN1_STRING *seq = NULL;
     915                 :          3 :         unsigned char *p, *pp = NULL;
     916                 :            :         int len;
     917                 :            : 
     918                 :          3 :         len = i2d_ESS_SIGNING_CERT(sc, NULL);
     919         [ -  + ]:          3 :         if (!(pp = (unsigned char *) OPENSSL_malloc(len)))
     920                 :            :                 {
     921                 :          0 :                 TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
     922                 :          0 :                 goto err;
     923                 :            :                 }
     924                 :          3 :         p = pp;
     925                 :          3 :         i2d_ESS_SIGNING_CERT(sc, &p);
     926 [ +  - ][ -  + ]:          3 :         if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len))
     927                 :            :                 {
     928                 :          0 :                 TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
     929                 :          0 :                 goto err;
     930                 :            :                 }
     931                 :          3 :         OPENSSL_free(pp); pp = NULL;
     932                 :          3 :         return PKCS7_add_signed_attribute(si, 
     933                 :            :                                           NID_id_smime_aa_signingCertificate,
     934                 :            :                                           V_ASN1_SEQUENCE, seq);
     935                 :            :  err:
     936                 :          0 :         ASN1_STRING_free(seq);
     937                 :          0 :         OPENSSL_free(pp);
     938                 :            : 
     939                 :          0 :         return 0;
     940                 :            :         }
     941                 :            : 
     942                 :            : 
     943                 :            : static ASN1_GENERALIZEDTIME *
     944                 :          3 : TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time, 
     945                 :            :                                    long sec, long usec, unsigned precision)
     946                 :            :         {
     947                 :          3 :         time_t time_sec = (time_t) sec;
     948                 :          3 :         struct tm *tm = NULL;   
     949                 :            :         char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS];
     950                 :          3 :         char *p = genTime_str;
     951                 :          3 :         char *p_end = genTime_str + sizeof(genTime_str);
     952                 :            : 
     953         [ +  - ]:          3 :         if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
     954                 :            :                 goto err;
     955                 :            : 
     956                 :            :         
     957         [ +  - ]:          3 :         if (!(tm = gmtime(&time_sec)))
     958                 :            :                 goto err;
     959                 :            : 
     960                 :            :         /* 
     961                 :            :          * Put "genTime_str" in GeneralizedTime format.  We work around the 
     962                 :            :          * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST 
     963                 :            :          * NOT include fractional seconds") and OpenSSL related functions to 
     964                 :            :          * meet the rfc3161 requirement: "GeneralizedTime syntax can include 
     965                 :            :          * fraction-of-second details". 
     966                 :            :          */                   
     967                 :          3 :         p += BIO_snprintf(p, p_end - p,
     968                 :            :                           "%04d%02d%02d%02d%02d%02d",
     969                 :          6 :                           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 
     970                 :            :                           tm->tm_hour, tm->tm_min, tm->tm_sec);
     971         [ -  + ]:          3 :         if (precision > 0)
     972                 :            :         {
     973                 :            :                 /* Add fraction of seconds (leave space for dot and null). */
     974                 :          0 :                 BIO_snprintf(p, 2 + precision, ".%ld", usec);
     975                 :            :                 /* We cannot use the snprintf return value, 
     976                 :            :                    because it might have been truncated. */
     977                 :          0 :                 p += strlen(p);
     978                 :            : 
     979                 :            :                 /* To make things a bit harder, X.690 | ISO/IEC 8825-1 provides
     980                 :            :                    the following restrictions for a DER-encoding, which OpenSSL
     981                 :            :                    (specifically ASN1_GENERALIZEDTIME_check() function) doesn't 
     982                 :            :                    support:
     983                 :            :                    "The encoding MUST terminate with a "Z" (which means "Zulu" 
     984                 :            :                    time). The decimal point element, if present, MUST be the 
     985                 :            :                    point option ".". The fractional-seconds elements, 
     986                 :            :                    if present, MUST omit all trailing 0's; 
     987                 :            :                    if the elements correspond to 0, they MUST be wholly
     988                 :            :                    omitted, and the decimal point element also MUST be
     989                 :            :                    omitted." */
     990                 :            :                 /* Remove trailing zeros. The dot guarantees the exit
     991                 :            :                    condition of this loop even if all the digits are zero. */
     992         [ #  # ]:          0 :                 while (*--p == '0')
     993                 :            :                         /* empty */;
     994                 :            :                 /* p points to either the dot or the last non-zero digit. */
     995         [ #  # ]:          0 :                 if (*p != '.') ++p;
     996                 :            :                 }
     997                 :            :         /* Add the trailing Z and the terminating null. */
     998                 :          3 :         *p++ = 'Z';
     999                 :          3 :         *p++ = '\0';
    1000                 :            : 
    1001                 :            :         /* Now call OpenSSL to check and set our genTime value */
    1002 [ +  - ][ +  - ]:          3 :         if (!asn1_time && !(asn1_time = M_ASN1_GENERALIZEDTIME_new()))
    1003                 :            :                 goto err;
    1004         [ -  + ]:          3 :         if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str))
    1005                 :            :                 {
    1006                 :          0 :                 ASN1_GENERALIZEDTIME_free(asn1_time);
    1007                 :          0 :                 goto err;
    1008                 :            :                 }
    1009                 :            : 
    1010                 :            :         return asn1_time;
    1011                 :            :  err:
    1012                 :          0 :         TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME);
    1013                 :          0 :         return NULL;
    1014                 :            :         }

Generated by: LCOV version 1.9