Coverage Report

Created: 2026-04-04 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nss/lib/pkcs12/p12plcy.c
Line
Count
Source
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#include "p12plcy.h"
6
#include "secoid.h"
7
#include "secport.h"
8
#include "secpkcs5.h"
9
#include "secerr.h"
10
#include "sechash.h"
11
12
#define PKCS12_NULL 0x0000
13
14
typedef struct pkcs12SuiteMapStr {
15
    SECOidTag algTag;
16
    unsigned int keyLengthBits; /* in bits */
17
    unsigned long suite;
18
    PRBool allowed;
19
    PRBool preferred;
20
} pkcs12SuiteMap;
21
22
static pkcs12SuiteMap pkcs12SuiteMaps[] = {
23
    { SEC_OID_RC4, 40, PKCS12_RC4_40, PR_FALSE, PR_FALSE },
24
    { SEC_OID_RC4, 128, PKCS12_RC4_128, PR_FALSE, PR_FALSE },
25
    { SEC_OID_RC2_CBC, 40, PKCS12_RC2_CBC_40, PR_FALSE, PR_TRUE },
26
    { SEC_OID_RC2_CBC, 128, PKCS12_RC2_CBC_128, PR_FALSE, PR_FALSE },
27
    { SEC_OID_DES_CBC, 64, PKCS12_DES_56, PR_FALSE, PR_FALSE },
28
    { SEC_OID_DES_EDE3_CBC, 192, PKCS12_DES_EDE3_168, PR_FALSE, PR_FALSE },
29
    { SEC_OID_AES_128_CBC, 128, PKCS12_AES_CBC_128, PR_FALSE, PR_FALSE },
30
    { SEC_OID_AES_192_CBC, 192, PKCS12_AES_CBC_192, PR_FALSE, PR_FALSE },
31
    { SEC_OID_AES_256_CBC, 256, PKCS12_AES_CBC_256, PR_FALSE, PR_FALSE },
32
    { SEC_OID_UNKNOWN, 0, PKCS12_NULL, PR_FALSE, PR_FALSE },
33
    { SEC_OID_UNKNOWN, 0, 0L, PR_FALSE, PR_FALSE }
34
};
35
36
/* determine if algid is an algorithm which is allowed */
37
static PRBool
38
sec_PKCS12Allowed(SECOidTag alg, PRUint32 needed)
39
20.2k
{
40
20.2k
    PRUint32 policy;
41
20.2k
    SECStatus rv;
42
43
20.2k
    rv = NSS_GetAlgorithmPolicy(alg, &policy);
44
20.2k
    if (rv != SECSuccess) {
45
0
        return PR_FALSE;
46
0
    }
47
20.2k
    if ((policy & needed) == needed) {
48
20.2k
        return PR_TRUE;
49
20.2k
    }
50
4
    return PR_FALSE;
51
20.2k
}
52
53
PRBool
54
SEC_PKCS12CipherAllowed(SECOidTag pbeAlg, SECOidTag hmacAlg)
55
0
{
56
0
    SECOidTag cipherAlg = SEC_PKCS5GetCryptoFromAlgTag(pbeAlg);
57
0
    SECOidTag hashAlg = SEC_PKCS5GetHashFromAlgTag(pbeAlg);
58
0
    if (cipherAlg == SEC_OID_UNKNOWN) {
59
        /* not a traditional PBE (PKCS5v1 or PKCS12)
60
         * Our PKCS #12 code accepts ciphers algs here
61
         * which get turned into PKCS 5v2 algids. In
62
         * this case we already have the cipher alg */
63
0
        cipherAlg = pbeAlg;
64
0
        hashAlg = HASH_GetHashOidTagByHMACOidTag(hmacAlg);
65
0
    }
66
0
    if ((cipherAlg == SEC_OID_UNKNOWN) || (hashAlg == SEC_OID_UNKNOWN)) {
67
0
        return PR_FALSE;
68
0
    }
69
0
    if (!sec_PKCS12Allowed(cipherAlg, NSS_USE_ALG_IN_PKCS12)) {
70
0
        return PR_FALSE;
71
0
    }
72
0
    return sec_PKCS12Allowed(hashAlg, NSS_USE_ALG_IN_PKCS12);
73
0
}
74
75
PRBool
76
SEC_PKCS12DecryptionAllowed(SECAlgorithmID *algid)
77
10.1k
{
78
10.1k
    SECOidTag algtag;
79
80
10.1k
    algtag = SEC_PKCS5GetCryptoAlgorithm(algid);
81
10.1k
    if (algtag == SEC_OID_UNKNOWN) {
82
89
        return PR_FALSE;
83
89
    }
84
85
10.0k
    if (!sec_PKCS12Allowed(algtag, NSS_USE_ALG_IN_PKCS12_DECRYPT)) {
86
3
        return PR_FALSE;
87
3
    }
88
89
10.0k
    algtag = SEC_PKCS5GetHashAlgorithm(algid);
90
10.0k
    if (algtag == SEC_OID_UNKNOWN) {
91
5
        return PR_FALSE;
92
5
    }
93
10.0k
    return sec_PKCS12Allowed(algtag, NSS_USE_ALG_IN_PKCS12_DECRYPT);
94
10.0k
}
95
96
PRBool
97
SEC_PKCS12IntegrityHashAllowed(SECOidTag hashAlg, PRBool verify)
98
205
{
99
205
    return sec_PKCS12Allowed(hashAlg, verify ? NSS_USE_ALG_IN_PKCS12_DECRYPT : NSS_USE_ALG_IN_PKCS12);
100
205
}
101
102
/* is any encryption allowed? */
103
PRBool
104
SEC_PKCS12IsEncryptionAllowed(void)
105
0
{
106
0
    int i;
107
108
0
    for (i = 0; pkcs12SuiteMaps[i].algTag != SEC_OID_UNKNOWN; i++) {
109
        /* we're going to return true here if any of the traditional
110
         * algorithms are enabled */
111
0
        if (sec_PKCS12Allowed(pkcs12SuiteMaps[i].algTag, NSS_USE_ALG_IN_PKCS12)) {
112
0
            return PR_TRUE;
113
0
        }
114
0
    }
115
116
0
    return PR_FALSE;
117
0
}
118
119
/* keep the traditional enable/disable for old ciphers so old applications
120
 * continue to work. This only works for the traditional pkcs12 values,
121
 * you need to use NSS_SetAlgorithmPolicy directly for other ciphers. */
122
SECStatus
123
SEC_PKCS12EnableCipher(long which, int on)
124
0
{
125
0
    int i;
126
0
    PRUint32 set = on ? NSS_USE_ALG_IN_PKCS12 : 0;
127
0
    PRUint32 clear = on ? 0 : NSS_USE_ALG_IN_PKCS12;
128
129
0
    for (i = 0; pkcs12SuiteMaps[i].suite != 0L; i++) {
130
0
        if (pkcs12SuiteMaps[i].suite == (unsigned long)which) {
131
0
            return NSS_SetAlgorithmPolicy(pkcs12SuiteMaps[i].algTag, set, clear);
132
0
        }
133
0
    }
134
0
    PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
135
0
    return SECFailure;
136
0
}
137
138
SECStatus
139
SEC_PKCS12SetPreferredCipher(long which, int on)
140
0
{
141
    /* nothing looked at the preferences in the suite maps, so this function
142
     * has always been a noop */
143
0
    return SECSuccess;
144
0
}