rpm 5.2.1

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

- File List
- Globals

rpmio/rpmnss.c
Go to the documentation of this file.

    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