rpm
5.2.1
|
00001 00005 #include "system.h" 00006 00007 #include <rpmiotypes.h> 00008 #define _RPMPGP_INTERNAL 00009 #if defined(WITH_NSS) 00010 #define _RPMNSS_INTERNAL 00011 #include <rpmnss.h> 00012 #endif 00013 00014 #include "debug.h" 00015 00016 #if defined(WITH_NSS) 00017 00018 /*@access pgpDig @*/ 00019 /*@access pgpDigParams @*/ 00020 00021 /*@-redecl@*/ 00022 /*@unchecked@*/ 00023 extern int _pgp_debug; 00024 00025 /*@unchecked@*/ 00026 extern int _pgp_print; 00027 /*@=redecl@*/ 00028 00029 /*@unchecked@*/ 00030 extern int _rpmnss_init; 00031 00032 static 00033 int rpmnssSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp) 00034 /*@modifies dig @*/ 00035 { 00036 rpmnss nss = dig->impl; 00037 int xx; 00038 00039 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00040 nss->sigalg = SEC_OID_UNKNOWN; 00041 switch (sigp->hash_algo) { 00042 case PGPHASHALGO_MD5: 00043 nss->sigalg = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; 00044 break; 00045 case PGPHASHALGO_SHA1: 00046 nss->sigalg = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; 00047 break; 00048 case PGPHASHALGO_RIPEMD160: 00049 break; 00050 case PGPHASHALGO_MD2: 00051 nss->sigalg = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION; 00052 break; 00053 case PGPHASHALGO_MD4: 00054 nss->sigalg = SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION; 00055 break; 00056 case PGPHASHALGO_TIGER192: 00057 break; 00058 case PGPHASHALGO_HAVAL_5_160: 00059 break; 00060 case PGPHASHALGO_SHA256: 00061 nss->sigalg = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; 00062 break; 00063 case PGPHASHALGO_SHA384: 00064 nss->sigalg = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; 00065 break; 00066 case PGPHASHALGO_SHA512: 00067 nss->sigalg = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; 00068 break; 00069 case PGPHASHALGO_SHA224: 00070 break; 00071 default: 00072 break; 00073 } 00074 if (nss->sigalg == SEC_OID_UNKNOWN) 00075 return 1; 00076 00077 xx = rpmDigestFinal(ctx, (void **)&dig->md5, &dig->md5len, 0); 00078 00079 /* Compare leading 16 bits of digest for quick check. */ 00080 return memcmp(dig->md5, sigp->signhash16, sizeof(sigp->signhash16)); 00081 } 00082 00083 static 00084 int rpmnssVerifyRSA(pgpDig dig) 00085 /*@*/ 00086 { 00087 rpmnss nss = dig->impl; 00088 int rc; 00089 00090 nss->item.type = siBuffer; 00091 nss->item.data = dig->md5; 00092 nss->item.len = (unsigned) dig->md5len; 00093 00094 /*@-moduncon -nullstate @*/ 00095 rc = (VFY_VerifyDigest(&nss->item, nss->rsa, nss->rsasig, nss->sigalg, NULL) == SECSuccess); 00096 /*@=moduncon =nullstate @*/ 00097 00098 return rc; 00099 } 00100 00101 static 00102 int rpmnssSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp) 00103 /*@modifies dig @*/ 00104 { 00105 rpmnss nss = dig->impl; 00106 int xx; 00107 00108 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00109 xx = rpmDigestFinal(ctx, (void **)&dig->sha1, &dig->sha1len, 0); 00110 00111 nss->sigalg = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; 00112 00113 /* Compare leading 16 bits of digest for quick check. */ 00114 return memcmp(dig->sha1, sigp->signhash16, sizeof(sigp->signhash16)); 00115 } 00116 00117 static 00118 int rpmnssVerifyDSA(pgpDig dig) 00119 /*@*/ 00120 { 00121 rpmnss nss = dig->impl; 00122 int rc; 00123 00124 nss->item.type = siBuffer; 00125 nss->item.data = dig->sha1; 00126 nss->item.len = (unsigned) dig->sha1len; 00127 00128 /*@-moduncon -nullstate @*/ 00129 rc = (VFY_VerifyDigest(&nss->item, nss->dsa, nss->dsasig, nss->sigalg, NULL) == SECSuccess); 00130 /*@=moduncon =nullstate @*/ 00131 00132 return rc; 00133 } 00134 00135 static 00136 int rpmnssSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp) 00137 /*@*/ 00138 { 00139 int rc = 1; /* XXX always fail. */ 00140 int xx; 00141 00142 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00143 xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0); 00144 00145 /* Compare leading 16 bits of digest for quick check. */ 00146 00147 return rc; 00148 } 00149 00150 static 00151 int rpmnssVerifyECDSA(/*@unused@*/pgpDig dig) 00152 /*@*/ 00153 { 00154 int rc = 0; /* XXX always fail. */ 00155 00156 return rc; 00157 } 00158 00162 static 00163 int rpmnssMpiSet(const char * pre, unsigned int lbits, 00164 /*@out@*/ void * dest, const rpmuint8_t * p, 00165 /*@null@*/ const rpmuint8_t * pend) 00166 /*@modifies *dest @*/ 00167 { 00168 unsigned int mbits = pgpMpiBits(p); 00169 unsigned int nbits; 00170 unsigned int nbytes; 00171 char * t = dest; 00172 unsigned int ix; 00173 00174 if (pend != NULL && (p + ((mbits+7) >> 3)) > pend) 00175 return 1; 00176 00177 if (mbits > lbits) 00178 return 1; 00179 00180 nbits = (lbits > mbits ? lbits : mbits); 00181 nbytes = ((nbits + 7) >> 3); 00182 ix = ((nbits - mbits) >> 3); 00183 00184 /*@-modfilesystem @*/ 00185 if (_pgp_debug) 00186 fprintf(stderr, "*** mbits %u nbits %u nbytes %u ix %u\n", mbits, nbits, nbytes, ix); 00187 if (ix > 0) memset(t, (int)'\0', ix); 00188 memcpy(t+ix, p+2, nbytes-ix); 00189 if (_pgp_debug && _pgp_print) 00190 fprintf(stderr, "\t %s %s", pre, pgpHexStr(dest, nbytes)); 00191 /*@=modfilesystem @*/ 00192 return 0; 00193 } 00194 00198 static 00199 /*@only@*/ /*@null@*/ 00200 SECItem * rpmnssMpiCopy(PRArenaPool * arena, /*@returned@*/ SECItem * item, 00201 const rpmuint8_t * p) 00202 /*@modifies item @*/ 00203 { 00204 unsigned int nbytes = pgpMpiLen(p)-2; 00205 00206 /*@-moduncon@*/ 00207 if (item == NULL) { 00208 if ((item = SECITEM_AllocItem(arena, item, nbytes)) == NULL) 00209 return item; 00210 } else { 00211 if (arena != NULL) 00212 item->data = PORT_ArenaGrow(arena, item->data, item->len, nbytes); 00213 else 00214 item->data = PORT_Realloc(item->data, nbytes); 00215 00216 if (item->data == NULL) { 00217 if (arena == NULL) 00218 SECITEM_FreeItem(item, PR_TRUE); 00219 return NULL; 00220 } 00221 } 00222 /*@=moduncon@*/ 00223 00224 memcpy(item->data, p+2, nbytes); 00225 item->len = nbytes; 00226 /*@-temptrans@*/ 00227 return item; 00228 /*@=temptrans@*/ 00229 } 00230 00231 static /*@null@*/ 00232 SECKEYPublicKey * rpmnssNewPublicKey(KeyType type) 00233 /*@*/ 00234 { 00235 PRArenaPool *arena; 00236 SECKEYPublicKey *key; 00237 00238 /*@-moduncon@*/ 00239 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 00240 if (arena == NULL) 00241 return NULL; 00242 00243 key = PORT_ArenaZAlloc(arena, sizeof(*key)); 00244 00245 if (key == NULL) { 00246 PORT_FreeArena(arena, PR_FALSE); 00247 return NULL; 00248 } 00249 /*@=moduncon@*/ 00250 00251 key->keyType = type; 00252 key->pkcs11ID = CK_INVALID_HANDLE; 00253 key->pkcs11Slot = NULL; 00254 key->arena = arena; 00255 /*@-nullret@*/ /* key->pkcs11Slot can be NULL */ 00256 return key; 00257 /*@=nullret@*/ 00258 } 00259 00260 static 00261 int rpmnssMpiItem(const char * pre, pgpDig dig, int itemno, 00262 const rpmuint8_t * p, /*@null@*/ const rpmuint8_t * pend) 00263 /*@*/ 00264 { 00265 rpmnss nss = dig->impl; 00266 int rc = 0; 00267 00268 /*@-moduncon@*/ 00269 switch (itemno) { 00270 default: 00271 assert(0); 00272 break; 00273 case 10: /* RSA m**d */ 00274 nss->rsasig = rpmnssMpiCopy(NULL, nss->rsasig, p); 00275 if (nss->rsasig == NULL) 00276 rc = 1; 00277 break; 00278 case 20: /* DSA r */ 00279 nss->item.type = 0; 00280 nss->item.len = 2 * (160/8); 00281 nss->item.data = xcalloc(1, nss->item.len); 00282 rc = rpmnssMpiSet(pre, 160, nss->item.data, p, pend); 00283 break; 00284 case 21: /* DSA s */ 00285 rc = rpmnssMpiSet(pre, 160, nss->item.data + (160/8), p, pend); 00286 if (nss->dsasig != NULL) 00287 SECITEM_FreeItem(nss->dsasig, PR_FALSE); 00288 if ((nss->dsasig = SECITEM_AllocItem(NULL, NULL, 0)) == NULL 00289 || DSAU_EncodeDerSig(nss->dsasig, &nss->item) != SECSuccess) 00290 rc = 1; 00291 nss->item.data = _free(nss->item.data); 00292 break; 00293 case 30: /* RSA n */ 00294 if (nss->rsa == NULL) 00295 nss->rsa = rpmnssNewPublicKey(rsaKey); 00296 if (nss->rsa == NULL) 00297 rc = 1; 00298 else 00299 (void) rpmnssMpiCopy(nss->rsa->arena, &nss->rsa->u.rsa.modulus, p); 00300 break; 00301 case 31: /* RSA e */ 00302 if (nss->rsa == NULL) 00303 nss->rsa = rpmnssNewPublicKey(rsaKey); 00304 if (nss->rsa == NULL) 00305 rc = 1; 00306 else 00307 (void) rpmnssMpiCopy(nss->rsa->arena, &nss->rsa->u.rsa.publicExponent, p); 00308 break; 00309 case 40: /* DSA p */ 00310 if (nss->dsa == NULL) 00311 nss->dsa = rpmnssNewPublicKey(dsaKey); 00312 if (nss->dsa == NULL) 00313 rc = 1; 00314 else 00315 (void) rpmnssMpiCopy(nss->dsa->arena, &nss->dsa->u.dsa.params.prime, p); 00316 break; 00317 case 41: /* DSA q */ 00318 if (nss->dsa == NULL) 00319 nss->dsa = rpmnssNewPublicKey(dsaKey); 00320 if (nss->dsa == NULL) 00321 rc = 1; 00322 else 00323 (void) rpmnssMpiCopy(nss->dsa->arena, &nss->dsa->u.dsa.params.subPrime, p); 00324 break; 00325 case 42: /* DSA g */ 00326 if (nss->dsa == NULL) 00327 nss->dsa = rpmnssNewPublicKey(dsaKey); 00328 if (nss->dsa == NULL) 00329 rc = 1; 00330 else 00331 (void) rpmnssMpiCopy(nss->dsa->arena, &nss->dsa->u.dsa.params.base, p); 00332 break; 00333 case 43: /* DSA y */ 00334 if (nss->dsa == NULL) 00335 nss->dsa = rpmnssNewPublicKey(dsaKey); 00336 if (nss->dsa == NULL) 00337 rc = 1; 00338 else 00339 (void) rpmnssMpiCopy(nss->dsa->arena, &nss->dsa->u.dsa.publicValue, p); 00340 break; 00341 } 00342 /*@=moduncon@*/ 00343 return rc; 00344 } 00345 00346 /*@-mustmod@*/ 00347 static 00348 void rpmnssClean(void * impl) 00349 /*@modifies impl @*/ 00350 { 00351 rpmnss nss = impl; 00352 /*@-moduncon@*/ 00353 if (nss != NULL) { 00354 if (nss->dsa != NULL) { 00355 SECKEY_DestroyPublicKey(nss->dsa); 00356 nss->dsa = NULL; 00357 } 00358 if (nss->dsasig != NULL) { 00359 SECITEM_ZfreeItem(nss->dsasig, PR_TRUE); 00360 nss->dsasig = NULL; 00361 } 00362 if (nss->rsa != NULL) { 00363 SECKEY_DestroyPublicKey(nss->rsa); 00364 nss->rsa = NULL; 00365 } 00366 if (nss->rsasig != NULL) { 00367 SECITEM_ZfreeItem(nss->rsasig, PR_TRUE); 00368 nss->rsasig = NULL; 00369 } 00370 /*@=moduncon@*/ 00371 } 00372 } 00373 /*@=mustmod@*/ 00374 00375 static /*@null@*/ 00376 void * rpmnssFree(/*@only@*/ void * impl) 00377 /*@*/ 00378 { 00379 rpmnss nss = impl; 00380 if (nss != NULL) { 00381 rpmnssClean(impl); 00382 nss = _free(nss); 00383 } 00384 return NULL; 00385 } 00386 00387 static 00388 void * rpmnssInit(void) 00389 /*@globals _rpmnss_init @*/ 00390 /*@modifies _rpmnss_init @*/ 00391 { 00392 rpmnss nss = xcalloc(1, sizeof(*nss)); 00393 00394 /*@-moduncon@*/ 00395 (void) NSS_NoDB_Init(NULL); 00396 /*@=moduncon@*/ 00397 _rpmnss_init = 1; 00398 00399 return (void *) nss; 00400 } 00401 00402 struct pgpImplVecs_s rpmnssImplVecs = { 00403 rpmnssSetRSA, rpmnssVerifyRSA, 00404 rpmnssSetDSA, rpmnssVerifyDSA, 00405 rpmnssSetECDSA, rpmnssVerifyECDSA, 00406 rpmnssMpiItem, rpmnssClean, 00407 rpmnssFree, rpmnssInit 00408 }; 00409 00410 #endif 00411