Coverage Report

Created: 2026-01-22 06:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nss/lib/smime/cmsreclist.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
 * CMS recipient list functions
7
 */
8
9
#include "cmslocal.h"
10
11
#include "cert.h"
12
#include "keyhi.h"
13
#include "secasn1.h"
14
#include "secitem.h"
15
#include "secoid.h"
16
#include "pk11func.h"
17
#include "prtime.h"
18
#include "secerr.h"
19
20
static int
21
nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos,
22
                            NSSCMSRecipient **recipient_list)
23
272
{
24
272
    int count = 0;
25
272
    int rlindex = 0;
26
272
    int i, j;
27
272
    NSSCMSRecipient *rle;
28
272
    NSSCMSRecipientInfo *ri;
29
272
    NSSCMSRecipientEncryptedKey *rek;
30
31
13.8k
    for (i = 0; recipientinfos[i] != NULL; i++) {
32
13.5k
        ri = recipientinfos[i];
33
13.5k
        switch (ri->recipientInfoType) {
34
13.3k
            case NSSCMSRecipientInfoID_KeyTrans:
35
13.3k
                if (recipient_list) {
36
6.69k
                    NSSCMSRecipientIdentifier *recipId =
37
6.69k
                        &ri->ri.keyTransRecipientInfo.recipientIdentifier;
38
39
6.69k
                    if (recipId->identifierType != NSSCMSRecipientID_IssuerSN &&
40
2.22k
                        recipId->identifierType != NSSCMSRecipientID_SubjectKeyID) {
41
0
                        PORT_SetError(SEC_ERROR_INVALID_ARGS);
42
0
                        return -1;
43
0
                    }
44
                    /* alloc one & fill it out */
45
6.69k
                    rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient));
46
6.69k
                    if (!rle)
47
0
                        return -1;
48
49
6.69k
                    rle->riIndex = i;
50
6.69k
                    rle->subIndex = -1;
51
6.69k
                    switch (recipId->identifierType) {
52
4.46k
                        case NSSCMSRecipientID_IssuerSN:
53
4.46k
                            rle->kind = RLIssuerSN;
54
4.46k
                            rle->id.issuerAndSN = recipId->id.issuerAndSN;
55
4.46k
                            break;
56
2.22k
                        case NSSCMSRecipientID_SubjectKeyID:
57
2.22k
                            rle->kind = RLSubjKeyID;
58
2.22k
                            rle->id.subjectKeyID = recipId->id.subjectKeyID;
59
2.22k
                            break;
60
0
                        default: /* we never get here because of identifierType check
61
                                    we done before. Leaving it to kill compiler warning */
62
0
                            break;
63
6.69k
                    }
64
6.69k
                    recipient_list[rlindex++] = rle;
65
6.69k
                } else {
66
6.69k
                    count++;
67
6.69k
                }
68
13.3k
                break;
69
13.3k
            case NSSCMSRecipientInfoID_KeyAgree:
70
196
                if (ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys == NULL)
71
0
                    break;
72
392
                for (j = 0; ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j] != NULL; j++) {
73
196
                    if (recipient_list) {
74
98
                        rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j];
75
                        /* alloc one & fill it out */
76
98
                        rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient));
77
98
                        if (!rle)
78
0
                            return -1;
79
80
98
                        rle->riIndex = i;
81
98
                        rle->subIndex = j;
82
98
                        switch (rek->recipientIdentifier.identifierType) {
83
98
                            case NSSCMSKeyAgreeRecipientID_IssuerSN:
84
98
                                rle->kind = RLIssuerSN;
85
98
                                rle->id.issuerAndSN = rek->recipientIdentifier.id.issuerAndSN;
86
98
                                break;
87
0
                            case NSSCMSKeyAgreeRecipientID_RKeyID:
88
0
                                rle->kind = RLSubjKeyID;
89
0
                                rle->id.subjectKeyID =
90
0
                                    rek->recipientIdentifier.id.recipientKeyIdentifier.subjectKeyIdentifier;
91
0
                                break;
92
98
                        }
93
98
                        recipient_list[rlindex++] = rle;
94
98
                    } else {
95
98
                        count++;
96
98
                    }
97
196
                }
98
196
                break;
99
196
            case NSSCMSRecipientInfoID_KEK:
100
                /* KEK is not implemented */
101
0
                break;
102
13.5k
        }
103
13.5k
    }
104
    /* if we have a recipient list, we return on success (-1, above, on failure) */
105
    /* otherwise, we return the count. */
106
272
    if (recipient_list) {
107
136
        recipient_list[rlindex] = NULL;
108
136
        return 0;
109
136
    } else {
110
136
        return count;
111
136
    }
112
272
}
113
114
NSSCMSRecipient **
115
nss_cms_recipient_list_create(NSSCMSRecipientInfo **recipientinfos)
116
136
{
117
136
    int count, rv;
118
136
    NSSCMSRecipient **recipient_list;
119
120
    /* count the number of recipient identifiers */
121
136
    count = nss_cms_recipients_traverse(recipientinfos, NULL);
122
136
    if (count <= 0) {
123
        /* no recipients? */
124
0
        PORT_SetError(SEC_ERROR_BAD_DATA);
125
#if 0
126
    PORT_SetErrorString("Cannot find recipient data in envelope.");
127
#endif
128
0
        return NULL;
129
0
    }
130
131
    /* allocate an array of pointers */
132
136
    recipient_list = (NSSCMSRecipient **)
133
136
        PORT_ZAlloc((count + 1) * sizeof(NSSCMSRecipient *));
134
136
    if (recipient_list == NULL)
135
0
        return NULL;
136
137
    /* now fill in the recipient_list */
138
136
    rv = nss_cms_recipients_traverse(recipientinfos, recipient_list);
139
136
    if (rv < 0) {
140
0
        nss_cms_recipient_list_destroy(recipient_list);
141
0
        return NULL;
142
0
    }
143
136
    return recipient_list;
144
136
}
145
146
void
147
nss_cms_recipient_list_destroy(NSSCMSRecipient **recipient_list)
148
136
{
149
136
    int i;
150
136
    NSSCMSRecipient *recipient;
151
152
6.92k
    for (i = 0; recipient_list[i] != NULL; i++) {
153
6.78k
        recipient = recipient_list[i];
154
6.78k
        if (recipient->cert)
155
0
            CERT_DestroyCertificate(recipient->cert);
156
6.78k
        if (recipient->privkey)
157
0
            SECKEY_DestroyPrivateKey(recipient->privkey);
158
6.78k
        if (recipient->slot)
159
0
            PK11_FreeSlot(recipient->slot);
160
6.78k
        PORT_Free(recipient);
161
6.78k
    }
162
136
    PORT_Free(recipient_list);
163
136
}
164
165
NSSCMSRecipientEncryptedKey *
166
NSS_CMSRecipientEncryptedKey_Create(PLArenaPool *poolp)
167
0
{
168
0
    return (NSSCMSRecipientEncryptedKey *)PORT_ArenaZAlloc(poolp,
169
0
                                                           sizeof(NSSCMSRecipientEncryptedKey));
170
0
}