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
00025
00026
00027
00028
00029 extern int _pgp_debug;
00030
00031
00032 extern int _pgp_print;
00033
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
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
00073
00074 static
00075 int rpmsslSetRSA( DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00076
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
00103
00104 xx = BN_hex2bn(&ssl->rsahm, hexstr);
00105
00106
00107
00108 if (_pgp_debug < 0) fprintf(stderr, "*** rsahm: %s\n", hexstr);
00109 hexstr = _free(hexstr);
00110
00111
00112
00113 s = dig->md5;
00114
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
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
00125 size_t nt = BN_bn2bin(s, t);
00126
00127
00128 if (nt < maxn) {
00129 size_t pad = (maxn - nt);
00130
00131 if (_pgp_debug < 0) fprintf(stderr, "\tmemmove(%p, %p, %u)\n", t+pad, t, (unsigned)nt);
00132
00133 memmove(t+pad, t, nt);
00134
00135 if (_pgp_debug < 0) fprintf(stderr, "\tmemset(%p, 0, %u)\n", t, (unsigned)pad);
00136
00137 memset(t, 0, pad);
00138 }
00139
00140 if (_pgp_debug < 0) hexdump(msg, t, maxn);
00141
00142 return t;
00143 }
00144
00145 static
00146 int rpmsslVerifyRSA(pgpDig dig)
00147
00148 {
00149 rpmssl ssl = dig->impl;
00150
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
00156 size_t i;
00157 int rc = 0;
00158 int xx;
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 for (i = 2; i < maxn; i++) {
00180 if (hm[i] == 0xff)
00181 continue;
00182 i++;
00183
00184 if (_pgp_debug < 0) hexdump("HM", hm + i, (maxn - i));
00185
00186 break;
00187 }
00188
00189
00190 if (_pgp_debug < 0) hexdump("HM", hm + (maxn - nb), nb);
00191 if (_pgp_debug < 0) hexdump(" C", c, nb);
00192
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( DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00204
00205 {
00206 int xx;
00207
00208 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00209
00210 xx = rpmDigestFinal(ctx, (void **)&dig->sha1, &dig->sha1len, 0);
00211
00212
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
00224
00225 rc = (DSA_do_verify(dig->sha1, (int)dig->sha1len, ssl->dsasig, ssl->dsa) == 1);
00226
00227
00228 return rc;
00229 }
00230
00231
00232 static
00233 int rpmsslSetECDSA( DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
00234
00235 {
00236 int rc = 1;
00237 int xx;
00238
00239 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
00240 xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0);
00241
00242
00243
00244 return rc;
00245 }
00246
00247 static
00248 int rpmsslVerifyECDSA(pgpDig dig)
00249
00250 {
00251 int rc = 0;
00252
00253 return rc;
00254 }
00255
00256 static
00257 int rpmsslMpiItem( const char * pre, pgpDig dig, int itemno,
00258 const rpmuint8_t * p,
00259 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
00267 switch (itemno) {
00268 default:
00269 assert(0);
00270 break;
00271 case 10:
00272 ssl->c = BN_bin2bn(p+2, nb, ssl->c);
00273 break;
00274 case 20:
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:
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:
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:
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:
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:
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:
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:
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
00308 return rc;
00309 }
00310
00311
00312 static
00313 void rpmsslClean(void * impl)
00314
00315 {
00316 rpmssl ssl = impl;
00317
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
00337 }
00338
00339
00340 static
00341 void * rpmsslFree( void * impl)
00342
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
00356 ERR_load_crypto_strings();
00357
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