rpm
5.2.1
|
00001 00005 #include "system.h" 00006 #include <rpmlog.h> 00007 00008 #include <rpmiotypes.h> 00009 #define _RPMPGP_INTERNAL 00010 #if defined(WITH_SSL) 00011 00012 #if defined(__LCLINT__) && !defined(__i386__) 00013 #define __i386__ 00014 #endif 00015 00016 #define _RPMSSL_INTERNAL 00017 #include <rpmssl.h> 00018 #endif 00019 00020 #include "debug.h" 00021 00022 #if defined(WITH_SSL) 00023 00024 /*@access pgpDig @*/ 00025 /*@access pgpDigParams @*/ 00026 00027 /*@-redecl@*/ 00028 /*@unchecked@*/ 00029 extern int _pgp_debug; 00030 00031 /*@unchecked@*/ 00032 extern int _pgp_print; 00033 /*@=redecl@*/ 00034 00040 static 00041 unsigned char nibble(char c) 00042 /*@*/ 00043 { 00044 if (c >= '0' && c <= '9') 00045 return (unsigned char) (c - '0'); 00046 if (c >= 'A' && c <= 'F') 00047 return (unsigned char)((int)(c - 'A') + 10); 00048 if (c >= 'a' && c <= 'f') 00049 return (unsigned char)((int)(c - 'a') + 10); 00050 return (unsigned char) '\0'; 00051 } 00052 00053 /*@-modfilesys@*/ 00054 static 00055 void hexdump(const char * msg, unsigned char * b, size_t blen) 00056 /*@*/ 00057 { 00058 static const char hex[] = "0123456789abcdef"; 00059 00060 fprintf(stderr, "*** %s:", msg); 00061 if (b != NULL) 00062 while (blen > 0) { 00063 fprintf(stderr, "%c%c", 00064 hex[ (unsigned)((*b >> 4) & 0x0f) ], 00065 hex[ (unsigned)((*b ) & 0x0f) ]); 00066 blen--; 00067 b++; 00068 } 00069 fprintf(stderr, "\n"); 00070 return; 00071 } 00072 /*@=modfilesys@*/ 00073 00074 static 00075 int rpmsslSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp) 00076 /*@modifies dig @*/ 00077 { 00078 rpmssl ssl = dig->impl; 00079 unsigned int nbits = BN_num_bits(ssl->c); 00080 unsigned int nb = (nbits + 7) >> 3; 00081 const char * prefix = rpmDigestASN1(ctx); 00082 const char * hexstr; 00083 const char * s; 00084 rpmuint8_t signhash16[2]; 00085 char * tt; 00086 int xx; 00087 00088 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00089 if (prefix == NULL) 00090 return 1; 00091 00092 xx = rpmDigestFinal(ctx, (void **)&dig->md5, &dig->md5len, 1); 00093 hexstr = tt = xmalloc(2 * nb + 1); 00094 memset(tt, (int) 'f', (2 * nb)); 00095 tt[0] = '0'; tt[1] = '0'; 00096 tt[2] = '0'; tt[3] = '1'; 00097 tt += (2 * nb) - strlen(prefix) - strlen(dig->md5) - 2; 00098 *tt++ = '0'; *tt++ = '0'; 00099 tt = stpcpy(tt, prefix); 00100 tt = stpcpy(tt, dig->md5); 00101 00102 /* Set RSA hash. */ 00103 /*@-moduncon -noeffectuncon @*/ 00104 xx = BN_hex2bn(&ssl->rsahm, hexstr); 00105 /*@=moduncon =noeffectuncon @*/ 00106 00107 /*@-modfilesys@*/ 00108 if (_pgp_debug < 0) fprintf(stderr, "*** rsahm: %s\n", hexstr); 00109 hexstr = _free(hexstr); 00110 /*@=modfilesys@*/ 00111 00112 /* Compare leading 16 bits of digest for quick check. */ 00113 s = dig->md5; 00114 /*@-type@*/ 00115 signhash16[0] = (rpmuint8_t) (nibble(s[0]) << 4) | nibble(s[1]); 00116 signhash16[1] = (rpmuint8_t) (nibble(s[2]) << 4) | nibble(s[3]); 00117 /*@=type@*/ 00118 return memcmp(signhash16, sigp->signhash16, sizeof(sigp->signhash16)); 00119 } 00120 00121 static unsigned char * rpmsslBN2bin(const char * msg, const BIGNUM * s, size_t maxn) 00122 { 00123 unsigned char * t = xcalloc(1, maxn); 00124 /*@-modunconnomods@*/ 00125 size_t nt = BN_bn2bin(s, t); 00126 /*@=modunconnomods@*/ 00127 00128 if (nt < maxn) { 00129 size_t pad = (maxn - nt); 00130 /*@-modfilesys@*/ 00131 if (_pgp_debug < 0) fprintf(stderr, "\tmemmove(%p, %p, %u)\n", t+pad, t, (unsigned)nt); 00132 /*@=modfilesys@*/ 00133 memmove(t+pad, t, nt); 00134 /*@-modfilesys@*/ 00135 if (_pgp_debug < 0) fprintf(stderr, "\tmemset(%p, 0, %u)\n", t, (unsigned)pad); 00136 /*@=modfilesys@*/ 00137 memset(t, 0, pad); 00138 } 00139 /*@-modfilesys@*/ 00140 if (_pgp_debug < 0) hexdump(msg, t, maxn); 00141 /*@=modfilesys@*/ 00142 return t; 00143 } 00144 00145 static 00146 int rpmsslVerifyRSA(pgpDig dig) 00147 /*@*/ 00148 { 00149 rpmssl ssl = dig->impl; 00150 /*@-moduncon@*/ 00151 size_t maxn = BN_num_bytes(ssl->rsa->n); 00152 unsigned char * hm = rpmsslBN2bin("hm", ssl->rsahm, maxn); 00153 unsigned char * c = rpmsslBN2bin(" c", ssl->c, maxn); 00154 size_t nb = RSA_public_decrypt((int)maxn, c, c, ssl->rsa, RSA_PKCS1_PADDING); 00155 /*@=moduncon@*/ 00156 size_t i; 00157 int rc = 0; 00158 int xx; 00159 00160 /* Verify RSA signature. */ 00161 /* XXX This is _NOT_ the correct openssl function to use: 00162 * rc = RSA_verify(type, m, m_len, sigbuf, siglen, ssl->rsa) 00163 * 00164 * Here's what needs doing (from OpenPGP reference sources in 1999): 00165 * static u32_t checkrsa(BIGNUM * a, RSA * key, u8_t * hash, int hlen) 00166 * { 00167 * u8_t dbuf[MAXSIGM]; 00168 * int j, ll; 00169 * 00170 * j = BN_bn2bin(a, dbuf); 00171 * ll = BN_num_bytes(key->n); 00172 * while (j < ll) 00173 * memmove(&dbuf[1], dbuf, j++), dbuf[0] = 0; 00174 * j = RSA_public_decrypt(ll, dbuf, dbuf, key, RSA_PKCS1_PADDING); 00175 * RSA_free(key); 00176 * return (j != hlen || memcmp(dbuf, hash, j)); 00177 * } 00178 */ 00179 for (i = 2; i < maxn; i++) { 00180 if (hm[i] == 0xff) 00181 continue; 00182 i++; 00183 /*@-modfilesys@*/ 00184 if (_pgp_debug < 0) hexdump("HM", hm + i, (maxn - i)); 00185 /*@=modfilesys@*/ 00186 break; 00187 } 00188 00189 /*@-modfilesys@*/ 00190 if (_pgp_debug < 0) hexdump("HM", hm + (maxn - nb), nb); 00191 if (_pgp_debug < 0) hexdump(" C", c, nb); 00192 /*@=modfilesys@*/ 00193 00194 rc = ((maxn - i) == nb && (xx = memcmp(hm+i, c, nb)) == 0); 00195 00196 c = _free(c); 00197 hm = _free(hm); 00198 00199 return rc; 00200 } 00201 00202 static 00203 int rpmsslSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp) 00204 /*@modifies dig @*/ 00205 { 00206 int xx; 00207 00208 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00209 /* Set DSA hash. */ 00210 xx = rpmDigestFinal(ctx, (void **)&dig->sha1, &dig->sha1len, 0); 00211 00212 /* Compare leading 16 bits of digest for quick check. */ 00213 return memcmp(dig->sha1, sigp->signhash16, sizeof(sigp->signhash16)); 00214 } 00215 00216 static 00217 int rpmsslVerifyDSA(pgpDig dig) 00218 /*@*/ 00219 { 00220 rpmssl ssl = dig->impl; 00221 int rc; 00222 00223 /* Verify DSA signature. */ 00224 /*@-moduncon@*/ 00225 rc = (DSA_do_verify(dig->sha1, (int)dig->sha1len, ssl->dsasig, ssl->dsa) == 1); 00226 /*@=moduncon@*/ 00227 00228 return rc; 00229 } 00230 00231 00232 static 00233 int rpmsslSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp) 00234 /*@*/ 00235 { 00236 int rc = 1; /* XXX always fail. */ 00237 int xx; 00238 00239 assert(sigp->hash_algo == rpmDigestAlgo(ctx)); 00240 xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0); 00241 00242 /* Compare leading 16 bits of digest for quick check. */ 00243 00244 return rc; 00245 } 00246 00247 static 00248 int rpmsslVerifyECDSA(/*@unused@*/pgpDig dig) 00249 /*@*/ 00250 { 00251 int rc = 0; /* XXX always fail. */ 00252 00253 return rc; 00254 } 00255 00256 static 00257 int rpmsslMpiItem(/*@unused@*/ const char * pre, pgpDig dig, int itemno, 00258 const rpmuint8_t * p, 00259 /*@unused@*/ /*@null@*/ const rpmuint8_t * pend) 00260 /*@*/ 00261 { 00262 rpmssl ssl = dig->impl; 00263 unsigned int nb = ((pgpMpiBits(p) + 7) >> 3); 00264 int rc = 0; 00265 00266 /*@-moduncon@*/ 00267 switch (itemno) { 00268 default: 00269 assert(0); 00270 break; 00271 case 10: /* RSA m**d */ 00272 ssl->c = BN_bin2bn(p+2, nb, ssl->c); 00273 break; 00274 case 20: /* DSA r */ 00275 if (ssl->dsasig == NULL) ssl->dsasig = DSA_SIG_new(); 00276 ssl->dsasig->r = BN_bin2bn(p+2, nb, ssl->dsasig->r); 00277 break; 00278 case 21: /* DSA s */ 00279 if (ssl->dsasig == NULL) ssl->dsasig = DSA_SIG_new(); 00280 ssl->dsasig->s = BN_bin2bn(p+2, nb, ssl->dsasig->s); 00281 break; 00282 case 30: /* RSA n */ 00283 if (ssl->rsa == NULL) ssl->rsa = RSA_new(); 00284 ssl->rsa->n = BN_bin2bn(p+2, nb, ssl->rsa->n); 00285 break; 00286 case 31: /* RSA e */ 00287 if (ssl->rsa == NULL) ssl->rsa = RSA_new(); 00288 ssl->rsa->e = BN_bin2bn(p+2, nb, ssl->rsa->e); 00289 break; 00290 case 40: /* DSA p */ 00291 if (ssl->dsa == NULL) ssl->dsa = DSA_new(); 00292 ssl->dsa->p = BN_bin2bn(p+2, nb, ssl->dsa->p); 00293 break; 00294 case 41: /* DSA q */ 00295 if (ssl->dsa == NULL) ssl->dsa = DSA_new(); 00296 ssl->dsa->q = BN_bin2bn(p+2, nb, ssl->dsa->q); 00297 break; 00298 case 42: /* DSA g */ 00299 if (ssl->dsa == NULL) ssl->dsa = DSA_new(); 00300 ssl->dsa->g = BN_bin2bn(p+2, nb, ssl->dsa->g); 00301 break; 00302 case 43: /* DSA y */ 00303 if (ssl->dsa == NULL) ssl->dsa = DSA_new(); 00304 ssl->dsa->pub_key = BN_bin2bn(p+2, nb, ssl->dsa->pub_key); 00305 break; 00306 } 00307 /*@=moduncon@*/ 00308 return rc; 00309 } 00310 00311 /*@-mustmod@*/ 00312 static 00313 void rpmsslClean(void * impl) 00314 /*@modifies impl @*/ 00315 { 00316 rpmssl ssl = impl; 00317 /*@-moduncon@*/ 00318 if (ssl != NULL) { 00319 if (ssl->dsa) { 00320 DSA_free(ssl->dsa); 00321 ssl->dsa = NULL; 00322 } 00323 if (ssl->dsasig) { 00324 DSA_SIG_free(ssl->dsasig); 00325 ssl->dsasig = NULL; 00326 } 00327 if (ssl->rsa) { 00328 RSA_free(ssl->rsa); 00329 ssl->rsa = NULL; 00330 } 00331 if (ssl->c) { 00332 BN_free(ssl->c); 00333 ssl->c = NULL; 00334 } 00335 } 00336 /*@=moduncon@*/ 00337 } 00338 /*@=mustmod@*/ 00339 00340 static /*@null@*/ 00341 void * rpmsslFree(/*@only@*/ void * impl) 00342 /*@modifies impl @*/ 00343 { 00344 rpmssl ssl = impl; 00345 rpmsslClean(impl); 00346 ssl = _free(ssl); 00347 return NULL; 00348 } 00349 00350 static 00351 void * rpmsslInit(void) 00352 /*@*/ 00353 { 00354 rpmssl ssl = xcalloc(1, sizeof(*ssl)); 00355 /*@-moduncon@*/ 00356 ERR_load_crypto_strings(); 00357 /*@=moduncon@*/ 00358 return (void *) ssl; 00359 } 00360 00361 struct pgpImplVecs_s rpmsslImplVecs = { 00362 rpmsslSetRSA, rpmsslVerifyRSA, 00363 rpmsslSetDSA, rpmsslVerifyDSA, 00364 rpmsslSetECDSA, rpmsslVerifyECDSA, 00365 rpmsslMpiItem, rpmsslClean, 00366 rpmsslFree, rpmsslInit 00367 }; 00368 00369 #endif 00370