Coverage Report

Created: 2024-11-21 07:03

/src/nss-nspr/nss/lib/certdb/xconst.c
Line
Count
Source (jump to first uncovered line)
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
static const SEC_ASN1Template CERTIA5TypeTemplate[] = {
28
    { SEC_ASN1_IA5_STRING }
29
};
30
31
SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate)
32
33
static const SEC_ASN1Template CERTPrivateKeyUsagePeriodTemplate[] = {
34
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTPrivKeyUsagePeriod) },
35
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
36
      offsetof(CERTPrivKeyUsagePeriod, notBefore),
37
      SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
38
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
39
      offsetof(CERTPrivKeyUsagePeriod, notAfter),
40
      SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
41
    { 0 }
42
};
43
44
const SEC_ASN1Template CERTAltNameTemplate[] = {
45
    { SEC_ASN1_CONSTRUCTED, offsetof(CERTAltNameEncodedContext, encodedGenName),
46
      CERT_GeneralNamesTemplate }
47
};
48
49
const SEC_ASN1Template CERTAuthInfoAccessItemTemplate[] = {
50
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthInfoAccess) },
51
    { SEC_ASN1_OBJECT_ID, offsetof(CERTAuthInfoAccess, method) },
52
    { SEC_ASN1_ANY, offsetof(CERTAuthInfoAccess, derLocation) },
53
    { 0 }
54
};
55
56
const SEC_ASN1Template CERTAuthInfoAccessTemplate[] = {
57
    { SEC_ASN1_SEQUENCE_OF, 0, CERTAuthInfoAccessItemTemplate }
58
};
59
60
SECStatus
61
CERT_EncodeSubjectKeyID(PLArenaPool *arena, const SECItem *srcString,
62
                        SECItem *encodedValue)
63
0
{
64
0
    SECStatus rv = SECSuccess;
65
66
0
    if (!srcString) {
67
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
68
0
        return SECFailure;
69
0
    }
70
0
    if (SEC_ASN1EncodeItem(arena, encodedValue, srcString,
71
0
                           CERTSubjectKeyIDTemplate) == NULL) {
72
0
        rv = SECFailure;
73
0
    }
74
75
0
    return (rv);
76
0
}
77
78
SECStatus
79
CERT_EncodePrivateKeyUsagePeriod(PLArenaPool *arena,
80
                                 CERTPrivKeyUsagePeriod *pkup,
81
                                 SECItem *encodedValue)
82
0
{
83
0
    SECStatus rv = SECSuccess;
84
85
0
    if (SEC_ASN1EncodeItem(arena, encodedValue, pkup,
86
0
                           CERTPrivateKeyUsagePeriodTemplate) == NULL) {
87
0
        rv = SECFailure;
88
0
    }
89
0
    return (rv);
90
0
}
91
92
CERTPrivKeyUsagePeriod *
93
CERT_DecodePrivKeyUsagePeriodExtension(PLArenaPool *arena, SECItem *extnValue)
94
0
{
95
0
    SECStatus rv;
96
0
    CERTPrivKeyUsagePeriod *pPeriod;
97
0
    SECItem newExtnValue;
98
99
    /* allocate the certificate policies structure */
100
0
    pPeriod = PORT_ArenaZNew(arena, CERTPrivKeyUsagePeriod);
101
0
    if (pPeriod == NULL) {
102
0
        goto loser;
103
0
    }
104
105
0
    pPeriod->arena = arena;
106
107
    /* copy the DER into the arena, since Quick DER returns data that points
108
       into the DER input, which may get freed by the caller */
109
0
    rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
110
0
    if (rv != SECSuccess) {
111
0
        goto loser;
112
0
    }
113
114
0
    rv = SEC_QuickDERDecodeItem(
115
0
        arena, pPeriod, CERTPrivateKeyUsagePeriodTemplate, &newExtnValue);
116
0
    if (rv != SECSuccess) {
117
0
        goto loser;
118
0
    }
119
0
    return pPeriod;
120
121
0
loser:
122
0
    return NULL;
123
0
}
124
125
SECStatus
126
CERT_EncodeIA5TypeExtension(PLArenaPool *arena, char *value,
127
                            SECItem *encodedValue)
128
0
{
129
0
    SECItem encodeContext;
130
0
    SECStatus rv = SECSuccess;
131
132
0
    PORT_Memset(&encodeContext, 0, sizeof(encodeContext));
133
134
0
    if (value != NULL) {
135
0
        encodeContext.data = (unsigned char *)value;
136
0
        encodeContext.len = strlen(value);
137
0
    }
138
0
    if (SEC_ASN1EncodeItem(arena, encodedValue, &encodeContext,
139
0
                           CERTIA5TypeTemplate) == NULL) {
140
0
        rv = SECFailure;
141
0
    }
142
143
0
    return (rv);
144
0
}
145
146
SECStatus
147
CERT_EncodeAltNameExtension(PLArenaPool *arena, CERTGeneralName *value,
148
                            SECItem *encodedValue)
149
0
{
150
0
    SECItem **encodedGenName;
151
0
    SECStatus rv = SECSuccess;
152
153
0
    encodedGenName = cert_EncodeGeneralNames(arena, value);
154
0
    if (SEC_ASN1EncodeItem(arena, encodedValue, &encodedGenName,
155
0
                           CERT_GeneralNamesTemplate) == NULL) {
156
0
        rv = SECFailure;
157
0
    }
158
159
0
    return rv;
160
0
}
161
162
CERTGeneralName *
163
CERT_DecodeAltNameExtension(PLArenaPool *reqArena, SECItem *EncodedAltName)
164
0
{
165
0
    SECStatus rv = SECSuccess;
166
0
    CERTAltNameEncodedContext encodedContext;
167
0
    SECItem *newEncodedAltName;
168
169
0
    if (!reqArena) {
170
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
171
0
        return NULL;
172
0
    }
173
174
0
    newEncodedAltName = SECITEM_ArenaDupItem(reqArena, EncodedAltName);
175
0
    if (!newEncodedAltName) {
176
0
        return NULL;
177
0
    }
178
179
0
    encodedContext.encodedGenName = NULL;
180
0
    PORT_Memset(&encodedContext, 0, sizeof(CERTAltNameEncodedContext));
181
0
    rv = SEC_QuickDERDecodeItem(reqArena, &encodedContext,
182
0
                                CERT_GeneralNamesTemplate, newEncodedAltName);
183
0
    if (rv == SECFailure) {
184
0
        goto loser;
185
0
    }
186
0
    if (encodedContext.encodedGenName && encodedContext.encodedGenName[0])
187
0
        return cert_DecodeGeneralNames(reqArena, encodedContext.encodedGenName);
188
    /* Extension contained an empty GeneralNames sequence */
189
    /* Treat as extension not found */
190
0
    PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
191
0
loser:
192
0
    return NULL;
193
0
}
194
195
SECStatus
196
CERT_EncodeNameConstraintsExtension(PLArenaPool *arena,
197
                                    CERTNameConstraints *value,
198
                                    SECItem *encodedValue)
199
0
{
200
0
    SECStatus rv = SECSuccess;
201
202
0
    rv = cert_EncodeNameConstraints(value, arena, encodedValue);
203
0
    return rv;
204
0
}
205
206
CERTNameConstraints *
207
CERT_DecodeNameConstraintsExtension(PLArenaPool *arena,
208
                                    const SECItem *encodedConstraints)
209
0
{
210
0
    return cert_DecodeNameConstraints(arena, encodedConstraints);
211
0
}
212
213
CERTAuthInfoAccess **
214
CERT_DecodeAuthInfoAccessExtension(PLArenaPool *reqArena,
215
                                   const SECItem *encodedExtension)
216
0
{
217
0
    CERTAuthInfoAccess **info = NULL;
218
0
    SECStatus rv;
219
0
    int i;
220
0
    SECItem *newEncodedExtension;
221
222
0
    if (!reqArena) {
223
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
224
0
        return NULL;
225
0
    }
226
227
0
    newEncodedExtension = SECITEM_ArenaDupItem(reqArena, encodedExtension);
228
0
    if (!newEncodedExtension) {
229
0
        return NULL;
230
0
    }
231
232
0
    rv = SEC_QuickDERDecodeItem(reqArena, &info, CERTAuthInfoAccessTemplate,
233
0
                                newEncodedExtension);
234
0
    if (rv != SECSuccess || info == NULL) {
235
0
        return NULL;
236
0
    }
237
238
0
    for (i = 0; info[i] != NULL; i++) {
239
0
        info[i]->location =
240
0
            CERT_DecodeGeneralName(reqArena, &(info[i]->derLocation), NULL);
241
0
    }
242
0
    return info;
243
0
}
244
245
SECStatus
246
CERT_EncodeInfoAccessExtension(PLArenaPool *arena, CERTAuthInfoAccess **info,
247
                               SECItem *dest)
248
0
{
249
0
    SECItem *dummy;
250
0
    int i;
251
252
0
    PORT_Assert(info != NULL);
253
0
    PORT_Assert(dest != NULL);
254
0
    if (info == NULL || dest == NULL) {
255
0
        return SECFailure;
256
0
    }
257
258
0
    for (i = 0; info[i] != NULL; i++) {
259
0
        if (CERT_EncodeGeneralName(info[i]->location, &(info[i]->derLocation),
260
0
                                   arena) == NULL)
261
            /* Note that this may leave some of the locations filled in. */
262
0
            return SECFailure;
263
0
    }
264
0
    dummy = SEC_ASN1EncodeItem(arena, dest, &info, CERTAuthInfoAccessTemplate);
265
0
    if (dummy == NULL) {
266
0
        return SECFailure;
267
0
    }
268
0
    return SECSuccess;
269
0
}