~ubuntu-branches/debian/sid/postfix/sid

« back to all changes in this revision

Viewing changes to src/tls/tls_verify.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones, LaMont Jones, localization folks
  • Date: 2014-02-11 07:44:30 UTC
  • mfrom: (1.1.41)
  • Revision ID: package-import@ubuntu.com-20140211074430-91tdwgjriazawdz4
Tags: 2.11.0-1
[LaMont Jones]

* New upstream release: 2.11.0

[localization folks]

* l10n: Updated German translations.  Closes: #734893 (Helge Kreutzmann)

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
/*      #define TLS_INTERNAL
8
8
/*      #include <tls.h>
9
9
/*
 
10
/*      int     tls_verify_certificate_callback(ok, ctx)
 
11
/*      int     ok;
 
12
/*      X509_STORE_CTX *ctx;
 
13
/*
 
14
/*      int     tls_log_verify_error(TLScontext)
 
15
/*      TLS_SESS_STATE *TLScontext;
 
16
/*
10
17
/*      char *tls_peer_CN(peercert, TLScontext)
11
18
/*      X509   *peercert;
12
19
/*      TLS_SESS_STATE *TLScontext;
18
25
/*      const char *tls_dns_name(gn, TLScontext)
19
26
/*      const GENERAL_NAME *gn;
20
27
/*      TLS_SESS_STATE *TLScontext;
21
 
/*
22
 
/*      char *tls_fingerprint(peercert, dgst)
23
 
/*      X509   *peercert;
24
 
/*      const char *dgst;
25
 
/*
26
 
/*      char *tls_pkey_fprint(peercert, dgst)
27
 
/*      X509   *peercert;
28
 
/*      const char *dgst;
29
 
/*
30
 
/*      int     tls_verify_certificate_callback(ok, ctx)
31
 
/*      int     ok;
32
 
/*      X509_STORE_CTX *ctx;
33
28
/* DESCRIPTION
 
29
/*      tls_verify_certificate_callback() is called several times (directly
 
30
/*      or indirectly) from crypto/x509/x509_vfy.c. It collects errors
 
31
/*      and trust information at each element of the trust chain.
 
32
/*      The last call at depth 0 sets the verification status based
 
33
/*      on the cumulative winner (lowest depth) of errors vs. trust.
 
34
/*      We always return 1 (continue the handshake) and handle trust
 
35
/*      and peer-name verification problems at the application level.
 
36
/*
 
37
/*      tls_log_verify_error() (called only when we care about the
 
38
/*      peer certificate, that is not when opportunistic) logs the
 
39
/*      reason why the certificate failed to be verified.
 
40
/*
34
41
/*      tls_peer_CN() returns the text CommonName for the peer
35
42
/*      certificate subject, or an empty string if no CommonName was
36
43
/*      found. The result is allocated with mymalloc() and must be
48
55
/*      are found, a null string is returned instead. Further sanity
49
56
/*      checks may be added if the need arises.
50
57
/*
51
 
/*      tls_fingerprint() returns a fingerprint of the the given
52
 
/*      certificate using the requested message digest. Panics if the
53
 
/*      (previously verified) digest algorithm is not found. The return
54
 
/*      value is dynamically allocated with mymalloc(), and the caller
55
 
/*      must eventually free it with myfree().
56
 
/*
57
 
/*      tls_pkey_fprint() returns a public-key fingerprint; in all
58
 
/*      other respects the function behaves as tls_fingerprint().
59
 
/*      The var_tls_bc_pkey_fprint variable enables an incorrect
60
 
/*      algorithm that was used in Postfix versions 2.9.[0-5].
61
 
/*      
62
 
/*      tls_verify_callback() is called several times (directly or
63
 
/*      indirectly) from crypto/x509/x509_vfy.c. It is called as
64
 
/*      a final check, and if it returns "0", the handshake is
65
 
/*      immediately shut down and the connection fails.
66
 
/*
67
 
/*      Postfix/TLS has two modes, the "opportunistic" mode and
68
 
/*      the "enforce" mode:
69
 
/*
70
 
/*      In the "opportunistic" mode we never want the connection
71
 
/*      to fail just because there is something wrong with the
72
 
/*      peer's certificate. After all, we would have sent or received
73
 
/*      the mail even if TLS weren't available.  Therefore the
74
 
/*      return value is always "1".
75
 
/*
76
 
/*      The SMTP client or server may require TLS (e.g. to protect
77
 
/*      passwords), while peer certificates are optional.  In this
78
 
/*      case we must return "1" even when we are unhappy with the
79
 
/*      peer certificate.  Only when peer certificates are required,
80
 
/*      certificate verification failure will result in immediate
81
 
/*      termination (return 0).
82
 
/*
83
 
/*      The only error condition not handled inside the OpenSSL
84
 
/*      library is the case of a too-long certificate chain. We
85
 
/*      test for this condition only if "ok = 1", that is, if
86
 
/*      verification didn't fail because of some earlier problem.
87
 
/*
88
58
/*      Arguments:
89
59
/* .IP ok
90
60
/*      Result of prior verification: non-zero means success.  In
99
69
/*      to be decoded and checked for validity.
100
70
/* .IP peercert
101
71
/*      Server or client X.509 certificate.
102
 
/* .IP dgst
103
 
/*      Name of a message digest algorithm suitable for computing secure
104
 
/*      (1st pre-image resistant) message digests of certificates. For now,
105
 
/*      md5, sha1, or member of SHA-2 family if supported by OpenSSL.
106
72
/* .IP TLScontext
107
73
/*      Server or client context for warning messages.
108
74
/* DIAGNOSTICS
149
115
#include <mymalloc.h>
150
116
#include <stringops.h>
151
117
 
152
 
/* Global library. */
153
 
 
154
 
#include <mail_params.h>
155
 
 
156
118
/* TLS library. */
157
119
 
158
120
#define TLS_INTERNAL
159
121
#include <tls.h>
160
122
 
161
 
/* Application-specific. */
162
 
 
163
 
static const char hexcodes[] = "0123456789ABCDEF";
 
123
/* update_error_state - safely stash away error state */
 
124
 
 
125
static void update_error_state(TLS_SESS_STATE *TLScontext, int depth,
 
126
                                       X509 *errorcert, int errorcode)
 
127
{
 
128
    /* No news is good news */
 
129
    if (TLScontext->errordepth >= 0 && TLScontext->errordepth <= depth)
 
130
        return;
 
131
 
 
132
    /*
 
133
     * The certificate pointer is stable during the verification callback,
 
134
     * but may be freed after the callback returns.  Since we delay error
 
135
     * reporting till later, we bump the refcount so we can rely on it still
 
136
     * being there until later.
 
137
     */
 
138
    if (TLScontext->errorcert != 0)
 
139
        X509_free(TLScontext->errorcert);
 
140
    if (errorcert != 0)
 
141
        CRYPTO_add(&errorcert->references, 1, CRYPTO_LOCK_X509);
 
142
    TLScontext->errorcert = errorcert;
 
143
    TLScontext->errorcode = errorcode;
 
144
    TLScontext->errordepth = depth;
 
145
}
164
146
 
165
147
/* tls_verify_certificate_callback - verify peer certificate info */
166
148
 
170
152
    X509   *cert;
171
153
    int     err;
172
154
    int     depth;
 
155
    int     max_depth;
173
156
    SSL    *con;
174
157
    TLS_SESS_STATE *TLScontext;
175
158
 
176
 
    depth = X509_STORE_CTX_get_error_depth(ctx);
 
159
    /* May be NULL as of OpenSSL 1.0, thanks for the API change! */
177
160
    cert = X509_STORE_CTX_get_current_cert(ctx);
 
161
    err = X509_STORE_CTX_get_error(ctx);
178
162
    con = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
179
163
    TLScontext = SSL_get_ex_data(con, TLScontext_index);
 
164
    depth = X509_STORE_CTX_get_error_depth(ctx);
 
165
 
 
166
    /* Don't log the internal root CA unless there's an unexpected error. */
 
167
    if (ok && TLScontext->tadepth > 0 && depth > TLScontext->tadepth)
 
168
        return (1);
180
169
 
181
170
    /*
182
 
     * The callback function is called repeatedly, first with the root
183
 
     * certificate, and then with each intermediate certificate ending with
184
 
     * the peer certificate.
185
 
     * 
186
 
     * With each call, the validity of the current certificate (usage bits,
187
 
     * attributes, expiration, ... checked by the OpenSSL library) is
188
 
     * available in the "ok" argument. Error details are available via
189
 
     * X509_STORE_CTX API.
190
 
     * 
191
 
     * We never terminate the SSL handshake in the verification callback, rather
192
 
     * we allow the TLS handshake to continue, but mark the session as
193
 
     * unverified. The application is responsible for closing any sessions
194
 
     * with unverified credentials.
195
 
     * 
196
 
     * Certificate chain depth limit violations are mis-reported by the OpenSSL
197
 
     * library, from SSL_CTX_set_verify(3):
 
171
     * Certificate chain depth limit violations are mis-reported by the
 
172
     * OpenSSL library, from SSL_CTX_set_verify(3):
198
173
     * 
199
174
     * The certificate verification depth set with SSL[_CTX]_verify_depth()
200
175
     * stops the verification at a certain depth. The error message produced
206
181
     * present at this depth. This disambiguates trust chain truncation from
207
182
     * an incomplete trust chain.
208
183
     */
209
 
    if (depth >= SSL_get_verify_depth(con)) {
 
184
    max_depth = SSL_get_verify_depth(con) - 1;
 
185
 
 
186
    /*
 
187
     * We never terminate the SSL handshake in the verification callback,
 
188
     * rather we allow the TLS handshake to continue, but mark the session as
 
189
     * unverified. The application is responsible for closing any sessions
 
190
     * with unverified credentials.
 
191
     */
 
192
    if (max_depth >= 0 && depth > max_depth) {
 
193
        X509_STORE_CTX_set_error(ctx, err = X509_V_ERR_CERT_CHAIN_TOO_LONG);
210
194
        ok = 0;
211
 
        X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_CHAIN_TOO_LONG);
212
195
    }
 
196
    if (ok == 0)
 
197
        update_error_state(TLScontext, depth, cert, err);
 
198
 
213
199
    if (TLScontext->log_mask & TLS_LOG_VERBOSE) {
214
 
        X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
215
 
        msg_info("%s: certificate verification depth=%d verify=%d subject=%s",
 
200
        if (cert)
 
201
            X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
 
202
        else
 
203
            strcpy(buf, "<unknown>");
 
204
        msg_info("%s: depth=%d verify=%d subject=%s",
216
205
                 TLScontext->namaddr, depth, ok, printable(buf, '?'));
217
206
    }
218
 
 
219
 
    /*
220
 
     * If no errors, or we are not logging verification errors, we are done.
221
 
     */
222
 
    if (ok || (TLScontext->log_mask & TLS_LOG_UNTRUSTED) == 0)
223
 
        return (1);
224
 
 
225
 
    /*
226
 
     * One counter-example is enough.
227
 
     */
228
 
    TLScontext->log_mask &= ~TLS_LOG_UNTRUSTED;
 
207
    return (1);
 
208
}
 
209
 
 
210
/* tls_log_verify_error - Report final verification error status */
 
211
 
 
212
void    tls_log_verify_error(TLS_SESS_STATE *TLScontext)
 
213
{
 
214
    char    buf[CCERT_BUFSIZ];
 
215
    int     err = TLScontext->errorcode;
 
216
    X509   *cert = TLScontext->errorcert;
 
217
    int     depth = TLScontext->errordepth;
229
218
 
230
219
#define PURPOSE ((depth>0) ? "CA": TLScontext->am_server ? "client": "server")
231
220
 
 
221
    if (err == X509_V_OK)
 
222
        return;
 
223
 
232
224
    /*
233
225
     * Specific causes for verification failure.
234
226
     */
235
 
    switch (err = X509_STORE_CTX_get_error(ctx)) {
 
227
    switch (err) {
 
228
    case X509_V_ERR_CERT_UNTRUSTED:
 
229
 
 
230
        /*
 
231
         * We expect the error cert to be the leaf, but it is likely
 
232
         * sufficient to omit it from the log, even less user confusion.
 
233
         */
 
234
        msg_info("certificate verification failed for %s: "
 
235
                 "not trusted by local or TLSA policy", TLScontext->namaddr);
 
236
        break;
236
237
    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
237
238
        msg_info("certificate verification failed for %s: "
238
239
                 "self-signed certificate", TLScontext->namaddr);
245
246
         * provided, but not found in CAfile/CApath. Either way, we don't
246
247
         * trust it.
247
248
         */
248
 
        X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),
249
 
                          buf, sizeof(buf));
 
249
        if (cert)
 
250
            X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf));
 
251
        else
 
252
            strcpy(buf, "<unknown>");
250
253
        msg_info("certificate verification failed for %s: untrusted issuer %s",
251
254
                 TLScontext->namaddr, printable(buf, '?'));
252
255
        break;
267
270
    case X509_V_ERR_CERT_CHAIN_TOO_LONG:
268
271
        msg_info("certificate verification failed for %s: "
269
272
                 "certificate chain longer than limit(%d)",
270
 
                 TLScontext->namaddr, SSL_get_verify_depth(con) - 1);
 
273
                 TLScontext->namaddr, depth - 1);
271
274
        break;
272
275
    default:
273
276
        msg_info("%s certificate verification failed for %s: num=%d:%s",
275
278
                 X509_verify_cert_error_string(err));
276
279
        break;
277
280
    }
278
 
 
279
 
    return (1);
280
281
}
281
282
 
282
283
#ifndef DONT_GRIPE
479
480
    char   *cn;
480
481
 
481
482
    cn = tls_text_name(X509_get_subject_name(peercert), NID_commonName,
482
 
                       "subject CN", TLScontext, DO_GRIPE);
 
483
                       "subject CN", TLScontext, DONT_GRIPE);
483
484
    return (cn ? cn : mystrdup(""));
484
485
}
485
486
 
499
500
    if ((cn = tls_text_name(name, NID_commonName,
500
501
                            "issuer CN", TLScontext, DONT_GRIPE)) == 0)
501
502
        cn = tls_text_name(name, NID_organizationName,
502
 
                           "issuer Organization", TLScontext, DO_GRIPE);
 
503
                           "issuer Organization", TLScontext, DONT_GRIPE);
503
504
    return (cn ? cn : mystrdup(""));
504
505
}
505
506
 
506
 
/* tls_fprint - compute and encode digest of DER-encoded object */
507
 
 
508
 
static char *tls_fprint(const char *buf, int len, const char *dgst)
509
 
{
510
 
    const char *myname = "tls_fprint";
511
 
    EVP_MD_CTX *mdctx;
512
 
    const EVP_MD *md_alg;
513
 
    unsigned char md_buf[EVP_MAX_MD_SIZE];
514
 
    unsigned int md_len;
515
 
    int     i;
516
 
    char   *result = 0;
517
 
 
518
 
    /* Previously available in "init" routine. */
519
 
    if ((md_alg = EVP_get_digestbyname(dgst)) == 0)
520
 
        msg_panic("%s: digest algorithm \"%s\" not found", myname, dgst);
521
 
 
522
 
    mdctx = EVP_MD_CTX_create();
523
 
    if (EVP_DigestInit_ex(mdctx, md_alg, NULL) == 0
524
 
        || EVP_DigestUpdate(mdctx, buf, len) == 0
525
 
        || EVP_DigestFinal_ex(mdctx, md_buf, &md_len) == 0)
526
 
        msg_fatal("%s: error computing %s message digest", myname, dgst);
527
 
    EVP_MD_CTX_destroy(mdctx);
528
 
 
529
 
    /* Check for OpenSSL contract violation */
530
 
    if (md_len > EVP_MAX_MD_SIZE || md_len >= INT_MAX / 3)
531
 
        msg_panic("%s: unexpectedly large %s digest size: %u",
532
 
                  myname, dgst, md_len);
533
 
 
534
 
    result = mymalloc(md_len * 3);
535
 
    for (i = 0; i < md_len; i++) {
536
 
        result[i * 3] = hexcodes[(md_buf[i] & 0xf0) >> 4U];
537
 
        result[(i * 3) + 1] = hexcodes[(md_buf[i] & 0x0f)];
538
 
        result[(i * 3) + 2] = (i + 1 != md_len) ? ':' : '\0';
539
 
    }
540
 
    return (result);
541
 
}
542
 
 
543
 
/* tls_fingerprint - extract certificate fingerprint */
544
 
 
545
 
char   *tls_fingerprint(X509 *peercert, const char *dgst)
546
 
{
547
 
    int     len;
548
 
    char   *buf;
549
 
    char   *buf2;
550
 
    char   *result;
551
 
 
552
 
    len = i2d_X509(peercert, NULL);
553
 
    buf2 = buf = mymalloc(len);
554
 
    i2d_X509(peercert, (unsigned char **)&buf2);
555
 
    if (buf2 - buf != len)
556
 
        msg_panic("i2d_X509 invalid result length");
557
 
 
558
 
    result = tls_fprint(buf, len, dgst);
559
 
    myfree(buf);
560
 
 
561
 
    return (result);
562
 
}
563
 
 
564
 
/* tls_pkey_fprint - extract public key fingerprint from certificate */
565
 
 
566
 
char   *tls_pkey_fprint(X509 *peercert, const char *dgst)
567
 
{
568
 
    if (var_tls_bc_pkey_fprint) {
569
 
        const char *myname = "tls_pkey_fprint";
570
 
        ASN1_BIT_STRING *key;
571
 
        char   *result;
572
 
 
573
 
        key = X509_get0_pubkey_bitstr(peercert);
574
 
        if (key == 0)
575
 
            msg_fatal("%s: error extracting legacy public-key fingerprint: %m",
576
 
                      myname);
577
 
 
578
 
        result = tls_fprint((char *) key->data, key->length, dgst);
579
 
        return (result);
580
 
    } else {
581
 
        int     len;
582
 
        char   *buf;
583
 
        char   *buf2;
584
 
        char   *result;
585
 
 
586
 
        len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(peercert), NULL);
587
 
        buf2 = buf = mymalloc(len);
588
 
        i2d_X509_PUBKEY(X509_get_X509_PUBKEY(peercert), (unsigned char **) &buf2);
589
 
        if (buf2 - buf != len)
590
 
            msg_panic("i2d_X509_PUBKEY invalid result length");
591
 
 
592
 
        result = tls_fprint(buf, len, dgst);
593
 
        myfree(buf);
594
 
        return (result);
595
 
    }
596
 
}
597
 
 
598
507
#endif