Coverage Report

Created: 2026-10-13 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nss/lib/certdb/xconst.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
/*
6
 * X.509 Extension Encoding
7
 */
8
9
#include "prtypes.h"
10
#include "seccomon.h"
11
#include "secdert.h"
12
#include "secoidt.h"
13
#include "secasn1t.h"
14
#include "secasn1.h"
15
#include "cert.h"
16
#include "secder.h"
17
#include "prprf.h"
18
#include "xconst.h"
19
#include "genname.h"
20
#include "secasn1.h"
21
#include "secerr.h"
22
23
static const SEC_ASN1Template CERTSubjectKeyIDTemplate[] = {
24
    { SEC_ASN1_OCTET_STRING }
25
};
26
27
SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate)
28
29
static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = {
30
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTPrivKeyUsagePeriod) },
31
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
32
      offsetof(CERTPrivKeyUsagePeriod, notBefore),
33
      SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
34
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
35
      offsetof(CERTPrivKeyUsagePeriod, notAfter),
36
      SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
37
    { 0 }
38
};
39
40
const SEC_ASN1Template CERTAltNameTemplate[] = {
41
    { SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName),
42
      CERT_GeneralNamesTemplate }
43
};
44
45
const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = {
46
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthInfoAccess) },
47
    { SEC_ASN1_OBJECT_ID, offsetof(CERTAuthInfoAccess, method) },
48
    { SEC_ASN1_ANY, offsetof(CERTAuthInfoAccess, derLocation) },
49
    { 0 }
50
};
51
52
const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = {
53
    { SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate }
54
};
55
56
SECStatus
57
CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem *srcString,
58
                        SECItem *encodedValue)
59
0
{
60
0
    SECStatus rv = SECSuccess;
61
62
0
    if (!srcString) {
63
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
64
0
        return SECFailure;
65
0
    }
66
0
    if (SEC_ASN1EncodeItem(arena, encodedValue, srcString,
67
0
                           CERTSubjectKeyIDTemplate) == NULL) {
68
0
        rv = SECFailure;
69
0
    }
70
71
0
    return (rv);
72
0
}
73
74
CERTPrivKeyUsagePeriod *
75
CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue)
76
0
{
77
0
    SECStatus rv;
78
0
    CERTPrivKeyUsagePeriod *pPeriod;
79
0
    SECItem newExtnValue;
80
81
    /* allocate the certificate policies structure */
82
0
    pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod);
83
0
    if (pPeriod == NULL) {
84
0
        goto loser;
85
0
    }
86
87
0
    pPeriod->arena = arena;
88
89
    /* copy the DER into the arena, since Quick DER returns data that points
90
       into the DER input, which may get freed by the caller */
91
0
    rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
92
0
    if (rv != SECSuccess) {
93
0
        goto loser;
94
0
    }
95
96
0
    rv = SEC_QuickDERDecodeItem(
97
0
        arena, pPeriod, CERTPrivateKeyUsagePeriodTemplate, &newExtnValue);
98
0
    if (rv != SECSuccess) {
99
0
        goto loser;
100
0
    }
101
0
    return pPeriod;
102
103
0
loser:
104
0
    return NULL;
105
0
}
106
107
SECStatus
108
CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value,
109
                            SECItem *encodedValue)
110
0
{
111
0
    SECItem **encodedGenName;
112
0
    SECStatus rv = SECSuccess;
113
114
0
    encodedGenName = cert_EncodeGeneralNames(arena, value);
115
0
    if (SEC_ASN1EncodeItem(arena, encodedValue, &encodedGenName,
116
0
                           CERT_GeneralNamesTemplate) == NULL) {
117
0
        rv = SECFailure;
118
0
    }
119
120
0
    return rv;
121
0
}
122
123
CERTGeneralName *
124
CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName)
125
12.3k
{
126
12.3k
    SECStatus rv = SECSuccess;
127
12.3k
    CERTAltNameEncodedContext encodedContext;
128
12.3k
    SECItem *newEncodedAltName;
129
130
12.3k
    if (!reqArena) {
131
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
132
0
        return NULL;
133
0
    }
134
135
12.3k
    newEncodedAltName = SECITEM_ArenaDupItem(reqArena, EncodedAltName);
136
12.3k
    if (!newEncodedAltName) {
137
0
        return NULL;
138
0
    }
139
140
12.3k
    encodedContext.encodedGenName = NULL;
141
12.3k
    PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext));
142
12.3k
    rv = SEC_QuickDERDecodeItem(reqArena, &encodedContext,
143
12.3k
                                CERT_GeneralNamesTemplate, newEncodedAltName);
144
12.3k
    if (rv == SECFailure) {
145
6.18k
        goto loser;
146
6.18k
    }
147
6.16k
    if (encodedContext.encodedGenName && encodedContext.encodedGenName[0])
148
5.36k
        return cert_DecodeGeneralNames(reqArena, encodedContext.encodedGenName);
149
    /* Extension contained an empty GeneralNames sequence */
150
    /* Treat as extension not found */
151
807
    PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
152
6.98k
loser:
153
6.98k
    return NULL;
154
807
}
155
156
SECStatus
157
CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
158
                                    CERTNameConstraints *value,
159
                                    SECItem *encodedValue)
160
0
{
161
0
    SECStatus rv = SECSuccess;
162
163
0
    rv = cert_EncodeNameConstraints(value, arena, encodedValue);
164
0
    return rv;
165
0
}
166
167
CERTNameConstraints *
168
CERT_DecodeNameConstraintsExtension(PLArenaPool *arena,
169
                                    const SECItem *encodedConstraints)
170
0
{
171
0
    return cert_DecodeNameConstraints(arena, encodedConstraints);
172
0
}
173
174
CERTAuthInfoAccess **
175
CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
176
                                   const SECItem *encodedExtension)
177
50
{
178
50
    CERTAuthInfoAccess **info = NULL;
179
50
    SECStatus rv;
180
50
    int i;
181
50
    SECItem *newEncodedExtension;
182
183
50
    if (!reqArena) {
184
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
185
0
        return NULL;
186
0
    }
187
188
50
    newEncodedExtension = SECITEM_ArenaDupItem(reqArena, encodedExtension);
189
50
    if (!newEncodedExtension) {
190
0
        return NULL;
191
0
    }
192
193
50
    rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate,
194
50
                                newEncodedExtension);
195
50
    if (rv != SECSuccess || info == NULL) {
196
14
        return NULL;
197
14
    }
198
199
103
    for (i = 0; info[i] != NULL; i++) {
200
67
        info[i]->location =
201
67
            CERT_DecodeGeneralName(reqArena, &(info[i]->derLocation), NULL);
202
67
    }
203
36
    return info;
204
50
}
205
206
SECStatus
207
CERT_EncodeInfoAccessExtension(PLArenaPool *arena, CERTAuthInfoAccess **info,
208
                               SECItem *dest)
209
0
{
210
0
    SECItem *dummy;
211
0
    int i;
212
213
0
    PORT_Assert(info != NULL);
214
0
    PORT_Assert(dest != NULL);
215
0
    if (info == NULL || dest == NULL) {
216
0
        return SECFailure;
217
0
    }
218
219
0
    for (i = 0; info[i] != NULL; i++) {
220
0
        if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation),
221
0
                                   arena) == NULL)
222
            /* Note that this may leave some of the locations filled in. */
223
0
            return SECFailure;
224
0
    }
225
0
    dummy = SEC_ASN1EncodeItem(arena, dest, &info, CERTAuthInfoAccessTemplate);
226
0
    if (dummy == NULL) {
227
0
        return SECFailure;
228
0
    }
229
0
    return SECSuccess;
230
0
}