components/openssl/openssl-1.0.1-fips-140/patches/33_cert_chain.patch
changeset 4370 7043c27399f1
parent 4367 2f56a3dac19a
child 4371 29fdb14099eb
equal deleted inserted replaced
4367:2f56a3dac19a 4370:7043c27399f1
     1 This patch comes from OpenSSL upstream code, and the change has been commited to OpenSSL 1.0.2.
       
     2   http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=fbd2164044f92383955a801ad1b2857d71e83f27
       
     3   http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=51e7a4378a78bb0870a2cdc5c524c230c929ebcb
       
     4   http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=2dabd822366df7b2608b55d5ca5f31d5d484cbaf
       
     5 
       
     6 Index: openssl/crypto/x509/x509_trs.c
       
     7 ============================================================================
       
     8 $ diff -ru crypto/x509/x509_trs.c crypto/x509/x509_trs.c 
       
     9 --- openssl/crypto/x509/x509_trs.c.orig    4 Dec 2012 17:26:04 -0000    1.133.2.11.2.6.2.3
       
    10 +++ openssl/crypto/x509/x509_trs.c    14 Dec 2012 14:30:45 -0000    1.133.2.11.2.6.2.4
       
    11 @@ -119,6 +119,14 @@ int X509_check_trust(X509 *x, int id, int flags)
       
    12      int idx;
       
    13      if (id == -1)
       
    14          return 1;
       
    15 +    /* We get this as a default value */
       
    16 +    if (id == 0) {
       
    17 +        int rv;
       
    18 +        rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
       
    19 +        if (rv != X509_TRUST_UNTRUSTED)
       
    20 +            return rv;
       
    21 +        return trust_compat(NULL, x, 0);
       
    22 +    }
       
    23      idx = X509_TRUST_get_by_id(id);
       
    24      if (idx == -1)
       
    25          return default_trust(id, x, flags);
       
    26 Index: openssl/crypto/x509/x509_vfy.c
       
    27 ============================================================================
       
    28 $ cvs diff -u -r1.105.2.9.2.4.2.3 -r1.105.2.9.2.4.2.4 x509_vfy.c
       
    29 --- openssl/crypto/x509/x509_vfy.c    14 Dec 2012 12:53:48 -0000    1.105.2.9.2.4.2.3
       
    30 +++ openssl/crypto/x509/x509_vfy.c    14 Dec 2012 14:30:46 -0000    1.105.2.9.2.4.2.4
       
    31 @@ -149,6 +149,33 @@
       
    32  }
       
    33  #endif
       
    34  
       
    35 +/* Given a certificate try and find an exact match in the store */
       
    36 +
       
    37 +static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
       
    38 +    {
       
    39 +    STACK_OF(X509) *certs;
       
    40 +    X509 *xtmp = NULL;
       
    41 +    int i;
       
    42 +    /* Lookup all certs with matching subject name */
       
    43 +    certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
       
    44 +    if (certs == NULL)
       
    45 +        return NULL;
       
    46 +    /* Look for exact match */
       
    47 +    for (i = 0; i < sk_X509_num(certs); i++)
       
    48 +        {
       
    49 +        xtmp = sk_X509_value(certs, i);
       
    50 +        if (!X509_cmp(xtmp, x))
       
    51 +            break;
       
    52 +        }
       
    53 +    if (i < sk_X509_num(certs))
       
    54 +        CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
       
    55 +    else
       
    56 +        xtmp = NULL;
       
    57 +    sk_X509_pop_free(certs, X509_free);
       
    58 +    return xtmp;
       
    59 +    }
       
    60 +
       
    61 +
       
    62  int X509_verify_cert(X509_STORE_CTX *ctx)
       
    63  {
       
    64      X509 *x, *xtmp, *chain_ss = NULL;
       
    65 @@ -304,8 +331,17 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
       
    66  
       
    67      /* we now have our chain, lets check it... */
       
    68  
       
    69 -    /* Is last certificate looked up self signed? */
       
    70 -    if (!ctx->check_issued(ctx, x, x)) {
       
    71 +    i = check_trust(ctx);
       
    72 +
       
    73 +    /* If explicitly rejected error */
       
    74 +    if (i == X509_TRUST_REJECTED)
       
    75 +        goto end;
       
    76 +    /*
       
    77 +     * If not explicitly trusted then indicate error unless it's a single
       
    78 +     * self signed certificate in which case we've indicated an error already
       
    79 +     * and set bad_chain == 1
       
    80 +     */
       
    81 +    if (i != X509_TRUST_TRUSTED && !bad_chain) {
       
    82          if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
       
    83              if (ctx->last_untrusted >= num)
       
    84                  ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
       
    85 @@ -340,14 +376,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
       
    86      ok = check_name_constraints(ctx);
       
    87  
       
    88      if (!ok)
       
    89 -        goto end;
       
    90 -
       
    91 -    /* The chain extensions are OK: check trust */
       
    92 -
       
    93 -    if (param->trust > 0)
       
    94 -        ok = check_trust(ctx);
       
    95 -
       
    96 -    if (!ok)
       
    97          goto end;
       
    98  
       
    99      /* We may as well copy down any DSA parameters that are required */
       
   100 @@ -630,28 +658,53 @@ static int check_name_constraints(X509_STORE_CTX *ctx)
       
   101  
       
   102  static int check_trust(X509_STORE_CTX *ctx)
       
   103  {
       
   104 -#ifdef OPENSSL_NO_CHAIN_VERIFY
       
   105 -    return 1;
       
   106 -#else
       
   107      int i, ok;
       
   108 -    X509 *x;
       
   109 +    X509 *x = NULL;
       
   110      int (*cb) (int xok, X509_STORE_CTX *xctx);
       
   111      cb = ctx->verify_cb;
       
   112 -/* For now just check the last certificate in the chain */
       
   113 -    i = sk_X509_num(ctx->chain) - 1;
       
   114 -    x = sk_X509_value(ctx->chain, i);
       
   115 -    ok = X509_check_trust(x, ctx->param->trust, 0);
       
   116 -    if (ok == X509_TRUST_TRUSTED)
       
   117 -        return 1;
       
   118 -    ctx->error_depth = i;
       
   119 -    ctx->current_cert = x;
       
   120 -    if (ok == X509_TRUST_REJECTED)
       
   121 -        ctx->error = X509_V_ERR_CERT_REJECTED;
       
   122 -    else
       
   123 -        ctx->error = X509_V_ERR_CERT_UNTRUSTED;
       
   124 -    ok = cb(0, ctx);
       
   125 -    return ok;
       
   126 -#endif
       
   127 +    /* Check all trusted certificates in chain */
       
   128 +    for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) {
       
   129 +        x = sk_X509_value(ctx->chain, i);
       
   130 +        ok = X509_check_trust(x, ctx->param->trust, 0);
       
   131 +        /* If explicitly trusted return trusted */
       
   132 +        if (ok == X509_TRUST_TRUSTED)
       
   133 +            return X509_TRUST_TRUSTED;
       
   134 +        /*
       
   135 +         * If explicitly rejected notify callback and reject if not
       
   136 +         * overridden.
       
   137 +         */
       
   138 +        if (ok == X509_TRUST_REJECTED) {
       
   139 +            ctx->error_depth = i;
       
   140 +            ctx->current_cert = x;
       
   141 +            ctx->error = X509_V_ERR_CERT_REJECTED;
       
   142 +            ok = cb(0, ctx);
       
   143 +            if (!ok)
       
   144 +                return X509_TRUST_REJECTED;
       
   145 +        }
       
   146 +    }
       
   147 +    /*
       
   148 +     * If we accept partial chains and have at least one trusted certificate
       
   149 +     * return success.
       
   150 +     */
       
   151 +    if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
       
   152 +        X509 *mx;
       
   153 +        if (ctx->last_untrusted < sk_X509_num(ctx->chain))
       
   154 +            return X509_TRUST_TRUSTED;
       
   155 +        x = sk_X509_value(ctx->chain, 0);
       
   156 +        mx = lookup_cert_match(ctx, x);
       
   157 +        if (mx) {
       
   158 +            (void)sk_X509_set(ctx->chain, 0, mx);
       
   159 +            X509_free(x);
       
   160 +            ctx->last_untrusted = 0;
       
   161 +            return X509_TRUST_TRUSTED;
       
   162 +        }
       
   163 +    }
       
   164 +
       
   165 +    /*
       
   166 +     * If no trusted certs in chain at all return untrusted and allow
       
   167 +     * standard (no issuer cert) etc errors to be indicated.
       
   168 +     */
       
   169 +    return X509_TRUST_UNTRUSTED;
       
   170  }
       
   171  
       
   172  static int check_revocation(X509_STORE_CTX *ctx)
       
   173 @@ -1526,6 +1579,8 @@ static int internal_verify(X509_STORE_CTX *ctx)
       
   174      if (ctx->check_issued(ctx, xi, xi))
       
   175          xs = xi;
       
   176      else {
       
   177 +        if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN && n == 0)
       
   178 +            return check_cert_time(ctx, xi);
       
   179          if (n <= 0) {
       
   180              ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
       
   181              ctx->current_cert = xi;
       
   182 Index: openssl/crypto/x509/x509_vfy.h
       
   183 ============================================================================
       
   184 $ cvs diff -u -r1.67.2.3.4.1 -r1.67.2.3.4.2 x509_vfy.h
       
   185 --- openssl/crypto/x509/x509_vfy.h    26 Sep 2012 13:50:42 -0000    1.67.2.3.4.1
       
   186 +++ openssl/crypto/x509/x509_vfy.h    14 Dec 2012 14:30:46 -0000    1.67.2.3.4.2
       
   187 @@ -406,6 +406,9 @@
       
   188  /* Check selfsigned CA signature */
       
   189  # define X509_V_FLAG_CHECK_SS_SIGNATURE          0x4000
       
   190  
       
   191 +/* Allow partial chains if at least one certificate is in trusted store */
       
   192 +# define X509_V_FLAG_PARTIAL_CHAIN               0x80000
       
   193 +
       
   194  # define X509_VP_FLAG_DEFAULT                    0x1
       
   195  # define X509_VP_FLAG_OVERWRITE                  0x2
       
   196  # define X509_VP_FLAG_RESET_FLAGS                0x4
       
   197 Index: openssl/apps/apps.c
       
   198 ============================================================================
       
   199 $ cvs diff -u -r1.133.2.11.2.6.2.3 -r1.133.2.11.2.6.2.4 apps.c
       
   200 --- openssl/apps/apps.c    4 Dec 2012 17:26:04 -0000    1.133.2.11.2.6.2.3
       
   201 +++ openssl/apps/apps.c    14 Dec 2012 14:30:45 -0000    1.133.2.11.2.6.2.4
       
   202 @@ -2238,6 +2238,8 @@
       
   203          flags |= X509_V_FLAG_NOTIFY_POLICY;
       
   204      else if (!strcmp(arg, "-check_ss_sig"))
       
   205          flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
       
   206 +    else if (!strcmp(arg, "-partial_chain"))
       
   207 +        flags |= X509_V_FLAG_PARTIAL_CHAIN;
       
   208      else
       
   209          return 0;
       
   210