rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

rpmnss.c
Go to the documentation of this file.
1
5 #include "system.h"
6
7 #include <rpmiotypes.h>
8 #define _RPMPGP_INTERNAL
9 #if defined(WITH_NSS)
10 #define _RPMNSS_INTERNAL
11 #include <rpmnss.h>
12 #endif
13
14 #include "debug.h"
15
16 #if defined(WITH_NSS)
17
18 /*@access pgpDig @*/
19 /*@access pgpDigParams @*/
20
21 /*@-redecl@*/
22 /*@unchecked@*/
23 extern int _pgp_debug;
24
25 /*@unchecked@*/
26 extern int _pgp_print;
27 /*@=redecl@*/
28
29 /*@unchecked@*/
30 extern int _rpmnss_init;
31
32 static
33 int rpmnssSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
34 /*@modifies dig @*/
35 {
36 rpmnss nss = dig->impl;
37 int xx;
38
39 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
40 nss->sigalg = SEC_OID_UNKNOWN;
41 switch (sigp->hash_algo) {
42 case PGPHASHALGO_MD5:
43 nss->sigalg = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
44 break;
45 case PGPHASHALGO_SHA1:
46 nss->sigalg = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
47 break;
48 case PGPHASHALGO_RIPEMD160:
49 break;
50 case PGPHASHALGO_MD2:
51 nss->sigalg = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION;
52 break;
53 case PGPHASHALGO_MD4:
54 nss->sigalg = SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION;
55 break;
56 case PGPHASHALGO_TIGER192:
57 break;
58 case PGPHASHALGO_HAVAL_5_160:
59 break;
60 case PGPHASHALGO_SHA256:
61 nss->sigalg = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
62 break;
63 case PGPHASHALGO_SHA384:
64 nss->sigalg = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
65 break;
66 case PGPHASHALGO_SHA512:
67 nss->sigalg = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
68 break;
69 case PGPHASHALGO_SHA224:
70 break;
71 default:
72 break;
73 }
74 if (nss->sigalg == SEC_OID_UNKNOWN)
75 return 1;
76
77 xx = rpmDigestFinal(ctx, (void **)&dig->md5, &dig->md5len, 0);
78
79 /* Compare leading 16 bits of digest for quick check. */
80 return memcmp(dig->md5, sigp->signhash16, sizeof(sigp->signhash16));
81 }
82
83 static
84 int rpmnssVerifyRSA(pgpDig dig)
85 /*@*/
86 {
87 rpmnss nss = dig->impl;
88 int rc;
89
90 nss->item.type = siBuffer;
91 nss->item.data = dig->md5;
92 nss->item.len = (unsigned) dig->md5len;
93
94 /*@-moduncon -nullstate @*/
95 rc = (VFY_VerifyDigest(&nss->item, nss->rsa, nss->rsasig, nss->sigalg, NULL) == SECSuccess);
96 /*@=moduncon =nullstate @*/
97
98 return rc;
99 }
100
101 static
102 int rpmnssSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
103 /*@modifies dig @*/
104 {
105 rpmnss nss = dig->impl;
106 int xx;
107
108 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
109 xx = rpmDigestFinal(ctx, (void **)&dig->sha1, &dig->sha1len, 0);
110
111 nss->sigalg = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
112
113 /* Compare leading 16 bits of digest for quick check. */
114 return memcmp(dig->sha1, sigp->signhash16, sizeof(sigp->signhash16));
115 }
116
117 static
118 int rpmnssVerifyDSA(pgpDig dig)
119 /*@*/
120 {
121 rpmnss nss = dig->impl;
122 int rc;
123
124 nss->item.type = siBuffer;
125 nss->item.data = dig->sha1;
126 nss->item.len = (unsigned) dig->sha1len;
127
128 /*@-moduncon -nullstate @*/
129 rc = (VFY_VerifyDigest(&nss->item, nss->dsa, nss->dsasig, nss->sigalg, NULL) == SECSuccess);
130 /*@=moduncon =nullstate @*/
131
132 return rc;
133 }
134
135 static
136 int rpmnssSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
137 /*@*/
138 {
139 int rc = 1; /* XXX always fail. */
140 int xx;
141
142 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
143 xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0);
144
145 /* Compare leading 16 bits of digest for quick check. */
146
147 return rc;
148 }
149
150 static
151 int rpmnssVerifyECDSA(/*@unused@*/pgpDig dig)
152 /*@*/
153 {
154 int rc = 0; /* XXX always fail. */
155
156 return rc;
157 }
158
162 static
163 int rpmnssMpiSet(const char * pre, unsigned int lbits,
164 /*@out@*/ void * dest, const rpmuint8_t * p,
165 /*@null@*/ const rpmuint8_t * pend)
166 /*@modifies *dest @*/
167 {
168 unsigned int mbits = pgpMpiBits(p);
169 unsigned int nbits;
170 unsigned int nbytes;
171 char * t = dest;
172 unsigned int ix;
173
174 if (pend != NULL && (p + ((mbits+7) >> 3)) > pend)
175 return 1;
176
177 if (mbits > lbits)
178 return 1;
179
180 nbits = (lbits > mbits ? lbits : mbits);
181 nbytes = ((nbits + 7) >> 3);
182 ix = ((nbits - mbits) >> 3);
183
184 /*@-modfilesystem @*/
185 if (_pgp_debug)
186 fprintf(stderr, "*** mbits %u nbits %u nbytes %u ix %u\n", mbits, nbits, nbytes, ix);
187 if (ix > 0) memset(t, (int)'\0', ix);
188 memcpy(t+ix, p+2, nbytes-ix);
189 if (_pgp_debug && _pgp_print)
190 fprintf(stderr, "\t %s %s", pre, pgpHexStr(dest, nbytes));
191 /*@=modfilesystem @*/
192 return 0;
193 }
194
198 static
199 /*@only@*/ /*@null@*/
200 SECItem * rpmnssMpiCopy(PRArenaPool * arena, /*@returned@*/ SECItem * item,
201 const rpmuint8_t * p)
202 /*@modifies item @*/
203 {
204 unsigned int nbytes = pgpMpiLen(p)-2;
205
206 /*@-moduncon@*/
207 if (item == NULL) {
208 if ((item = SECITEM_AllocItem(arena, item, nbytes)) == NULL)
209 return item;
210 } else {
211 if (arena != NULL)
212 item->data = PORT_ArenaGrow(arena, item->data, item->len, nbytes);
213 else
214 item->data = PORT_Realloc(item->data, nbytes);
215
216 if (item->data == NULL) {
217 if (arena == NULL)
218 SECITEM_FreeItem(item, PR_TRUE);
219 return NULL;
220 }
221 }
222 /*@=moduncon@*/
223
224 memcpy(item->data, p+2, nbytes);
225 item->len = nbytes;
226 /*@-temptrans@*/
227 return item;
228 /*@=temptrans@*/
229 }
230
231 static /*@null@*/
232 SECKEYPublicKey * rpmnssNewPublicKey(KeyType type)
233 /*@*/
234 {
235 PRArenaPool *arena;
236 SECKEYPublicKey *key;
237
238 /*@-moduncon@*/
239 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
240 if (arena == NULL)
241 return NULL;
242
243 key = PORT_ArenaZAlloc(arena, sizeof(*key));
244
245 if (key == NULL) {
246 PORT_FreeArena(arena, PR_FALSE);
247 return NULL;
248 }
249 /*@=moduncon@*/
250
251 key->keyType = type;
252 key->pkcs11ID = CK_INVALID_HANDLE;
253 key->pkcs11Slot = NULL;
254 key->arena = arena;
255 /*@-nullret@*/ /* key->pkcs11Slot can be NULL */
256 return key;
257 /*@=nullret@*/
258 }
259
260 static
261 int rpmnssMpiItem(const char * pre, pgpDig dig, int itemno,
262 const rpmuint8_t * p, /*@null@*/ const rpmuint8_t * pend)
263 /*@*/
264 {
265 rpmnss nss = dig->impl;
266 int rc = 0;
267
268 /*@-moduncon@*/
269 switch (itemno) {
270 default:
271 assert(0);
272 break;
273 case 10: /* RSA m**d */
274 nss->rsasig = rpmnssMpiCopy(NULL, nss->rsasig, p);
275 if (nss->rsasig == NULL)
276 rc = 1;
277 break;
278 case 20: /* DSA r */
279 nss->item.type = 0;
280 nss->item.len = 2 * (160/8);
281 nss->item.data = xcalloc(1, nss->item.len);
282 rc = rpmnssMpiSet(pre, 160, nss->item.data, p, pend);
283 break;
284 case 21: /* DSA s */
285 rc = rpmnssMpiSet(pre, 160, nss->item.data + (160/8), p, pend);
286 if (nss->dsasig != NULL)
287 SECITEM_FreeItem(nss->dsasig, PR_FALSE);
288 if ((nss->dsasig = SECITEM_AllocItem(NULL, NULL, 0)) == NULL
289 || DSAU_EncodeDerSig(nss->dsasig, &nss->item) != SECSuccess)
290 rc = 1;
291 nss->item.data = _free(nss->item.data);
292 break;
293 case 30: /* RSA n */
294 if (nss->rsa == NULL)
295 nss->rsa = rpmnssNewPublicKey(rsaKey);
296 if (nss->rsa == NULL)
297 rc = 1;
298 else
299 (void) rpmnssMpiCopy(nss->rsa->arena, &nss->rsa->u.rsa.modulus, p);
300 break;
301 case 31: /* RSA e */
302 if (nss->rsa == NULL)
303 nss->rsa = rpmnssNewPublicKey(rsaKey);
304 if (nss->rsa == NULL)
305 rc = 1;
306 else
307 (void) rpmnssMpiCopy(nss->rsa->arena, &nss->rsa->u.rsa.publicExponent, p);
308 break;
309 case 40: /* DSA p */
310 if (nss->dsa == NULL)
311 nss->dsa = rpmnssNewPublicKey(dsaKey);
312 if (nss->dsa == NULL)
313 rc = 1;
314 else
315 (void) rpmnssMpiCopy(nss->dsa->arena, &nss->dsa->u.dsa.params.prime, p);
316 break;
317 case 41: /* DSA q */
318 if (nss->dsa == NULL)
319 nss->dsa = rpmnssNewPublicKey(dsaKey);
320 if (nss->dsa == NULL)
321 rc = 1;
322 else
323 (void) rpmnssMpiCopy(nss->dsa->arena, &nss->dsa->u.dsa.params.subPrime, p);
324 break;
325 case 42: /* DSA g */
326 if (nss->dsa == NULL)
327 nss->dsa = rpmnssNewPublicKey(dsaKey);
328 if (nss->dsa == NULL)
329 rc = 1;
330 else
331 (void) rpmnssMpiCopy(nss->dsa->arena, &nss->dsa->u.dsa.params.base, p);
332 break;
333 case 43: /* DSA y */
334 if (nss->dsa == NULL)
335 nss->dsa = rpmnssNewPublicKey(dsaKey);
336 if (nss->dsa == NULL)
337 rc = 1;
338 else
339 (void) rpmnssMpiCopy(nss->dsa->arena, &nss->dsa->u.dsa.publicValue, p);
340 break;
341 }
342 /*@=moduncon@*/
343 return rc;
344 }
345
346 /*@-mustmod@*/
347 static
348 void rpmnssClean(void * impl)
349 /*@modifies impl @*/
350 {
351 rpmnss nss = impl;
352 /*@-moduncon@*/
353 if (nss != NULL) {
354 if (nss->dsa != NULL) {
355 SECKEY_DestroyPublicKey(nss->dsa);
356 nss->dsa = NULL;
357 }
358 if (nss->dsasig != NULL) {
359 SECITEM_ZfreeItem(nss->dsasig, PR_TRUE);
360 nss->dsasig = NULL;
361 }
362 if (nss->rsa != NULL) {
363 SECKEY_DestroyPublicKey(nss->rsa);
364 nss->rsa = NULL;
365 }
366 if (nss->rsasig != NULL) {
367 SECITEM_ZfreeItem(nss->rsasig, PR_TRUE);
368 nss->rsasig = NULL;
369 }
370 /*@=moduncon@*/
371 }
372 }
373 /*@=mustmod@*/
374
375 static /*@null@*/
376 void * rpmnssFree(/*@only@*/ void * impl)
377 /*@*/
378 {
379 rpmnss nss = impl;
380 if (nss != NULL) {
381 rpmnssClean(impl);
382 nss = _free(nss);
383 }
384 return NULL;
385 }
386
387 static
388 void * rpmnssInit(void)
389 /*@globals _rpmnss_init @*/
390 /*@modifies _rpmnss_init @*/
391 {
392 rpmnss nss = xcalloc(1, sizeof(*nss));
393
394 /*@-moduncon@*/
395 (void) NSS_NoDB_Init(NULL);
396 /*@=moduncon@*/
397 _rpmnss_init = 1;
398
399 return (void *) nss;
400 }
401
402 struct pgpImplVecs_s rpmnssImplVecs = {
403 rpmnssSetRSA, rpmnssVerifyRSA,
404 rpmnssSetDSA, rpmnssVerifyDSA,
405 rpmnssSetECDSA, rpmnssVerifyECDSA,
406 rpmnssMpiItem, rpmnssClean,
407 rpmnssFree, rpmnssInit
408 };
409
410 #endif
411