~ubuntu-branches/ubuntu/maverick/nss/maverick

« back to all changes in this revision

Viewing changes to mozilla/security/nss/lib/certdb/certdb.c

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2009-06-16 13:23:47 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20090616132347-311ysb8oep74b98y
Tags: 3.12.3-0ubuntu1
* new upstream release 3.12.3 RTM (NSS_3_12_3_RTM) (LP: #387751)
* adjust patches to changed upstream code base
  - update debian/patches/38_kbsd.patch
* needs nspr >= 4.7.4
  - update debian/control
* update 85_security_load.patch to latest debian version
  - update debian/patches/85_security_load.patch
* add new symbols for 3.12.3
  - update debian/libnss3-1d.symbols

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 *
21
21
 * Contributor(s):
22
22
 *    Aaron Spangler <aaron@spangler.ods.org>
 
23
 *    Kaspar Brand <mozbugzilla@velox.ch>
23
24
 *
24
25
 * Alternatively, the contents of this file may be used under the terms of
25
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
38
39
/*
39
40
 * Certificate handling code
40
41
 *
41
 
 * $Id: certdb.c,v 1.92 2008/05/16 03:38:39 nelson%bolyard.com Exp $
 
42
 * $Id: certdb.c,v 1.100 2009/03/23 02:18:19 nelson%bolyard.com Exp $
42
43
 */
43
44
 
44
45
#include "nssilock.h"
52
53
#include "genname.h"
53
54
#include "keyhi.h"
54
55
#include "secitem.h"
55
 
#include "mcom_db.h"
56
56
#include "certdb.h"
57
57
#include "prprf.h"
58
58
#include "sechash.h"
939
939
        goto loser;
940
940
    }
941
941
 
 
942
    /* determine if this is a root cert */
 
943
    cert->isRoot = cert_IsRootCert(cert);
 
944
 
942
945
    /* initialize the certType */
943
946
    rv = cert_GetCertType(cert);
944
947
    if ( rv != SECSuccess ) {
945
948
        goto loser;
946
949
    }
947
950
 
948
 
    /* determine if this is a root cert */
949
 
    cert->isRoot = cert_IsRootCert(cert);
950
 
 
951
951
    tmpname = CERT_NameToAscii(&cert->subject);
952
952
    if ( tmpname != NULL ) {
953
953
        cert->subjectName = PORT_ArenaStrdup(cert->arena, tmpname);
1447
1447
** returns SECFailure with SSL_ERROR_BAD_CERT_DOMAIN if no match,
1448
1448
** returns SECFailure with some other error code if another error occurs.
1449
1449
**
1450
 
** may modify cn, so caller must pass a modifiable copy.
 
1450
** This function may modify string cn, so caller must pass a modifiable copy.
1451
1451
*/
1452
1452
static SECStatus
1453
1453
cert_TestHostName(char * cn, const char * hn)
1454
1454
{
1455
 
    int regvalid = PORT_RegExpValid(cn);
1456
 
    if (regvalid != NON_SXP) {
1457
 
        SECStatus rv;
1458
 
        /* cn is a regular expression, try to match the shexp */
1459
 
        int match = PORT_RegExpCaseSearch(hn, cn);
1460
 
 
1461
 
        if ( match == 0 ) {
1462
 
            rv = SECSuccess;
1463
 
        } else {
1464
 
            PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
1465
 
            rv = SECFailure;
1466
 
        }
1467
 
        return rv;
1468
 
    } 
1469
 
    /* cn is not a regular expression */
1470
 
 
1471
 
    /* compare entire hn with cert name */
 
1455
    static int useShellExp = -1;
 
1456
 
 
1457
    if (useShellExp < 0) {
 
1458
        useShellExp = (NULL != PR_GetEnv("NSS_USE_SHEXP_IN_CERT_NAME"));
 
1459
    }
 
1460
    if (useShellExp) {
 
1461
        /* Backward compatible code, uses Shell Expressions (SHEXP). */
 
1462
        int regvalid = PORT_RegExpValid(cn);
 
1463
        if (regvalid != NON_SXP) {
 
1464
            SECStatus rv;
 
1465
            /* cn is a regular expression, try to match the shexp */
 
1466
            int match = PORT_RegExpCaseSearch(hn, cn);
 
1467
 
 
1468
            if ( match == 0 ) {
 
1469
                rv = SECSuccess;
 
1470
            } else {
 
1471
                PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
 
1472
                rv = SECFailure;
 
1473
            }
 
1474
            return rv;
 
1475
        }
 
1476
    } else {
 
1477
        /* New approach conforms to RFC 2818. */
 
1478
        char *wildcard    = PORT_Strchr(cn, '*');
 
1479
        char *firstcndot  = PORT_Strchr(cn, '.');
 
1480
        char *secondcndot = firstcndot ? PORT_Strchr(firstcndot+1, '.') : NULL;
 
1481
        char *firsthndot  = PORT_Strchr(hn, '.');
 
1482
 
 
1483
        /* For a cn pattern to be considered valid, the wildcard character...
 
1484
         * - may occur only in a DNS name with at least 3 components, and
 
1485
         * - may occur only as last character in the first component, and
 
1486
         * - may be preceded by additional characters
 
1487
         */
 
1488
        if (wildcard && secondcndot && secondcndot[1] && firsthndot 
 
1489
            && firstcndot  - wildcard  == 1
 
1490
            && secondcndot - firstcndot > 1
 
1491
            && PORT_Strrchr(cn, '*') == wildcard
 
1492
            && !PORT_Strncasecmp(cn, hn, wildcard - cn)
 
1493
            && !PORT_Strcasecmp(firstcndot, firsthndot)) {
 
1494
            /* valid wildcard pattern match */
 
1495
            return SECSuccess;
 
1496
        }
 
1497
    }
 
1498
    /* String cn has no wildcard or shell expression.  
 
1499
     * Compare entire string hn with cert name. 
 
1500
     */
1472
1501
    if (PORT_Strcasecmp(hn, cn) == 0) {
1473
1502
        return SECSuccess;
1474
1503
    }
1475
 
            
 
1504
 
1476
1505
    PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
1477
1506
    return SECFailure;
1478
1507
}
1523
1552
                ** so must copy it.  
1524
1553
                */
1525
1554
                int cnLen = current->name.other.len;
1526
 
                if (cnLen + 1 > cnBufLen) {
1527
 
                    cnBufLen = cnLen + 1;
 
1555
                rv = CERT_RFC1485_EscapeAndQuote(cn, cnBufLen, 
 
1556
                                            current->name.other.data, cnLen);
 
1557
                if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_OUTPUT_LEN) {
 
1558
                    cnBufLen = cnLen * 3 + 3; /* big enough for worst case */
1528
1559
                    cn = (char *)PORT_ArenaAlloc(arena, cnBufLen);
1529
1560
                    if (!cn)
1530
1561
                        goto fail;
 
1562
                    rv = CERT_RFC1485_EscapeAndQuote(cn, cnBufLen, 
 
1563
                                            current->name.other.data, cnLen);
1531
1564
                }
1532
 
                PORT_Memcpy(cn, current->name.other.data, cnLen);
1533
 
                cn[cnLen] = 0;
1534
 
                rv = cert_TestHostName(cn ,hn);
 
1565
                if (rv == SECSuccess)
 
1566
                    rv = cert_TestHostName(cn ,hn);
1535
1567
                if (rv == SECSuccess)
1536
1568
                    goto finish;
1537
1569
            }
2107
2139
    SEC_DestroyCrl (crl);
2108
2140
}
2109
2141
 
2110
 
 
 
2142
static int
 
2143
cert_Version(CERTCertificate *cert)
 
2144
{
 
2145
    int version = 0;
 
2146
    if (cert && cert->version.data && cert->version.len) {
 
2147
        version = DER_GetInteger(&cert->version);
 
2148
        if (version < 0)
 
2149
            version = 0;
 
2150
    }
 
2151
    return version;
 
2152
}
 
2153
 
 
2154
static unsigned int
 
2155
cert_ComputeTrustOverrides(CERTCertificate *cert, unsigned int cType)
 
2156
{
 
2157
    CERTCertTrust *trust = cert->trust;
 
2158
 
 
2159
    if (trust && (trust->sslFlags |
 
2160
                  trust->emailFlags |
 
2161
                  trust->objectSigningFlags)) {
 
2162
 
 
2163
        if (trust->sslFlags & (CERTDB_VALID_PEER|CERTDB_TRUSTED)) 
 
2164
            cType |= NS_CERT_TYPE_SSL_SERVER|NS_CERT_TYPE_SSL_CLIENT;
 
2165
        if (trust->sslFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA)) 
 
2166
            cType |= NS_CERT_TYPE_SSL_CA;
 
2167
#if defined(CERTDB_NOT_TRUSTED)
 
2168
        if (trust->sslFlags & CERTDB_NOT_TRUSTED) 
 
2169
            cType &= ~(NS_CERT_TYPE_SSL_SERVER|NS_CERT_TYPE_SSL_CLIENT|
 
2170
                       NS_CERT_TYPE_SSL_CA);
 
2171
#endif
 
2172
        if (trust->emailFlags & (CERTDB_VALID_PEER|CERTDB_TRUSTED)) 
 
2173
            cType |= NS_CERT_TYPE_EMAIL;
 
2174
        if (trust->emailFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA)) 
 
2175
            cType |= NS_CERT_TYPE_EMAIL_CA;
 
2176
#if defined(CERTDB_NOT_TRUSTED)
 
2177
        if (trust->emailFlags & CERTDB_NOT_TRUSTED) 
 
2178
            cType &= ~(NS_CERT_TYPE_EMAIL|NS_CERT_TYPE_EMAIL_CA);
 
2179
#endif
 
2180
        if (trust->objectSigningFlags & (CERTDB_VALID_PEER|CERTDB_TRUSTED)) 
 
2181
            cType |= NS_CERT_TYPE_OBJECT_SIGNING;
 
2182
        if (trust->objectSigningFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA)) 
 
2183
            cType |= NS_CERT_TYPE_OBJECT_SIGNING_CA;
 
2184
#if defined(CERTDB_NOT_TRUSTED)
 
2185
        if (trust->objectSigningFlags & CERTDB_NOT_TRUSTED) 
 
2186
            cType &= ~(NS_CERT_TYPE_OBJECT_SIGNING|
 
2187
                       NS_CERT_TYPE_OBJECT_SIGNING_CA);
 
2188
#endif
 
2189
    }
 
2190
    return cType;
 
2191
}
2111
2192
 
2112
2193
/*
2113
2194
 * Does a cert belong to a CA?  We decide based on perm database trust
2116
2197
PRBool
2117
2198
CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype)
2118
2199
{
2119
 
    CERTCertTrust *trust;
2120
 
    SECStatus rv;
2121
 
    unsigned int type;
2122
 
    PRBool ret;
2123
 
 
2124
 
    ret = PR_FALSE;
2125
 
    type = 0;
2126
 
 
2127
 
    if ( cert->trust && (cert->trust->sslFlags|cert->trust->emailFlags|
2128
 
                                cert->trust->objectSigningFlags)) {
2129
 
        trust = cert->trust;
2130
 
        if ( ( ( trust->sslFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA ) ||
2131
 
           ( ( trust->sslFlags & CERTDB_TRUSTED_CA ) == CERTDB_TRUSTED_CA ) ) {
2132
 
            ret = PR_TRUE;
2133
 
            type |= NS_CERT_TYPE_SSL_CA;
2134
 
        }
2135
 
        
2136
 
        if ( ( ( trust->emailFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA ) ||
2137
 
          ( ( trust->emailFlags & CERTDB_TRUSTED_CA ) == CERTDB_TRUSTED_CA ) ) {
2138
 
            ret = PR_TRUE;
2139
 
            type |= NS_CERT_TYPE_EMAIL_CA;
2140
 
        }
2141
 
        
2142
 
        if ( ( ( trust->objectSigningFlags & CERTDB_VALID_CA ) 
2143
 
                                                == CERTDB_VALID_CA ) ||
2144
 
          ( ( trust->objectSigningFlags & CERTDB_TRUSTED_CA ) 
2145
 
                                                == CERTDB_TRUSTED_CA ) ) {
2146
 
            ret = PR_TRUE;
2147
 
            type |= NS_CERT_TYPE_OBJECT_SIGNING_CA;
2148
 
        }
 
2200
    unsigned int cType = cert->nsCertType;
 
2201
    PRBool ret = PR_FALSE;
 
2202
 
 
2203
    if (cType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA | 
 
2204
                NS_CERT_TYPE_OBJECT_SIGNING_CA)) {
 
2205
        ret = PR_TRUE;
2149
2206
    } else {
2150
 
        if ( cert->nsCertType &
2151
 
            ( NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA |
2152
 
             NS_CERT_TYPE_OBJECT_SIGNING_CA ) ) {
 
2207
        SECStatus rv;
 
2208
        CERTBasicConstraints constraints;
 
2209
 
 
2210
        rv = CERT_FindBasicConstraintExten(cert, &constraints);
 
2211
        if (rv == SECSuccess && constraints.isCA) {
2153
2212
            ret = PR_TRUE;
2154
 
            type = (cert->nsCertType & NS_CERT_TYPE_CA);
2155
 
        } else {
2156
 
            CERTBasicConstraints constraints;
2157
 
            rv = CERT_FindBasicConstraintExten(cert, &constraints);
2158
 
            if ( rv == SECSuccess ) {
2159
 
                if ( constraints.isCA ) {
2160
 
                    ret = PR_TRUE;
2161
 
                    type = (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
2162
 
                }
2163
 
            } 
 
2213
            cType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
2164
2214
        } 
2165
 
 
2166
 
        /* finally check if it's a FORTEZZA V1 CA */
2167
 
        if (ret == PR_FALSE) {
2168
 
            if (fortezzaIsCA(cert)) {
2169
 
                ret = PR_TRUE;
2170
 
                type = (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
2171
 
            }
2172
 
        }
2173
2215
    }
2174
2216
 
2175
 
    /* the isRoot flag trumps all */
2176
 
    if (cert->isRoot) {
 
2217
    /* finally check if it's an X.509 v1 root or FORTEZZA V1 CA */
 
2218
    if (!ret && 
 
2219
        ((cert->isRoot && cert_Version(cert) < SEC_CERTIFICATE_VERSION_3) ||
 
2220
         fortezzaIsCA(cert) )) {
2177
2221
        ret = PR_TRUE;
2178
 
        /* set only these by default, same as above */
2179
 
        type = (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
 
2222
        cType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
2180
2223
    }
 
2224
    /* Now apply trust overrides, if any */
 
2225
    cType = cert_ComputeTrustOverrides(cert, cType);
 
2226
    ret = (cType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA |
 
2227
                    NS_CERT_TYPE_OBJECT_SIGNING_CA)) ? PR_TRUE : PR_FALSE;
2181
2228
 
2182
 
    if ( rettype != NULL ) {
2183
 
        *rettype = type;
 
2229
    if (rettype != NULL) {
 
2230
        *rettype = cType;
2184
2231
    }
2185
 
    
2186
 
    return(ret);
 
2232
    return ret;
2187
2233
}
2188
2234
 
2189
2235
PRBool
2360
2406
 * NOTE - don't allow encode of govt-approved or invisible bits
2361
2407
 */
2362
2408
SECStatus
2363
 
CERT_DecodeTrustString(CERTCertTrust *trust, char *trusts)
 
2409
CERT_DecodeTrustString(CERTCertTrust *trust, const char *trusts)
2364
2410
{
2365
2411
    unsigned int i;
2366
2412
    unsigned int *pflags;