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
00019
00020
00021
00022
00023 extern int _pgp_debug;
00024
00025
00026 extern int _pgp_print;
00027
00028
00029
00030 extern int _rpmnss_init;
00031
00032 static
00033 int rpmnssSetRSA( DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00034
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
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
00095 rc = (VFY_VerifyDigest(&nss->item, nss->rsa, nss->rsasig, nss->sigalg, NULL) == SECSuccess);
00096
00097
00098 return rc;
00099 }
00100
00101 static
00102 int rpmnssSetDSA( DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00103
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
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
00129 rc = (VFY_VerifyDigest(&nss->item, nss->dsa, nss->dsasig, nss->sigalg, NULL) == SECSuccess);
00130
00131
00132 return rc;
00133 }
00134
00135 static
00136 int rpmnssSetECDSA( DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00137
00138 {
00139 int rc = 1;
00140 int xx;
00141
00142 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00143 xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0);
00144
00145
00146
00147 return rc;
00148 }
00149
00150 static
00151 int rpmnssVerifyECDSA(pgpDig dig)
00152
00153 {
00154 int rc = 0;
00155
00156 return rc;
00157 }
00158
00162 static
00163 int rpmnssMpiSet(const char * pre, unsigned int lbits,
00164 void * dest, const rpmuint8_t * p,
00165 const rpmuint8_t * pend)
00166
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
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
00192 return 0;
00193 }
00194
00198 static
00199
00200 SECItem * rpmnssMpiCopy(PRArenaPool * arena, SECItem * item,
00201 const rpmuint8_t * p)
00202
00203 {
00204 unsigned int nbytes = pgpMpiLen(p)-2;
00205
00206
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
00223
00224 memcpy(item->data, p+2, nbytes);
00225 item->len = nbytes;
00226
00227 return item;
00228
00229 }
00230
00231 static
00232 SECKEYPublicKey * rpmnssNewPublicKey(KeyType type)
00233
00234 {
00235 PRArenaPool *arena;
00236 SECKEYPublicKey *key;
00237
00238
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
00250
00251 key->keyType = type;
00252 key->pkcs11ID = CK_INVALID_HANDLE;
00253 key->pkcs11Slot = NULL;
00254 key->arena = arena;
00255
00256 return key;
00257
00258 }
00259
00260 static
00261 int rpmnssMpiItem(const char * pre, pgpDig dig, int itemno,
00262 const rpmuint8_t * p, const rpmuint8_t * pend)
00263
00264 {
00265 rpmnss nss = dig->impl;
00266 int rc = 0;
00267
00268
00269 switch (itemno) {
00270 default:
00271 assert(0);
00272 break;
00273 case 10:
00274 nss->rsasig = rpmnssMpiCopy(NULL, nss->rsasig, p);
00275 if (nss->rsasig == NULL)
00276 rc = 1;
00277 break;
00278 case 20:
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:
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:
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:
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:
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:
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:
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:
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
00343 return rc;
00344 }
00345
00346
00347 static
00348 void rpmnssClean(void * impl)
00349
00350 {
00351 rpmnss nss = impl;
00352
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
00371 }
00372 }
00373
00374
00375 static
00376 void * rpmnssFree( 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
00390
00391 {
00392 rpmnss nss = xcalloc(1, sizeof(*nss));
00393
00394
00395 (void) NSS_NoDB_Init(NULL);
00396
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