rpm 5.2.1

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

- File List
- Globals

rpmssl.c
Go to the documentation of this file.
1
5 #include "system.h"
6 #include <rpmlog.h>
7
8 #include <rpmiotypes.h>
9 #define _RPMPGP_INTERNAL
10 #if defined(WITH_SSL)
11
12 #if defined(__LCLINT__) && !defined(__i386__)
13 #define __i386__
14 #endif
15
16 #define _RPMSSL_INTERNAL
17 #include <rpmssl.h>
18 #endif
19
20 #include "debug.h"
21
22 #if defined(WITH_SSL)
23
24 /*@access pgpDig @*/
25 /*@access pgpDigParams @*/
26
27 /*@-redecl@*/
28 /*@unchecked@*/
29 extern int _pgp_debug;
30
31 /*@unchecked@*/
32 extern int _pgp_print;
33 /*@=redecl@*/
34
40 static
41 unsigned char nibble(char c)
42 /*@*/
43 {
44 if (c >= '0' && c <= '9')
45 return (unsigned char) (c - '0');
46 if (c >= 'A' && c <= 'F')
47 return (unsigned char)((int)(c - 'A') + 10);
48 if (c >= 'a' && c <= 'f')
49 return (unsigned char)((int)(c - 'a') + 10);
50 return (unsigned char) '\0';
51 }
52
53 /*@-modfilesys@*/
54 static
55 void hexdump(const char * msg, unsigned char * b, size_t blen)
56 /*@*/
57 {
58 static const char hex[] = "0123456789abcdef";
59
60 fprintf(stderr, "*** %s:", msg);
61 if (b != NULL)
62 while (blen > 0) {
63 fprintf(stderr, "%c%c",
64 hex[ (unsigned)((*b >> 4) & 0x0f) ],
65 hex[ (unsigned)((*b ) & 0x0f) ]);
66 blen--;
67 b++;
68 }
69 fprintf(stderr, "\n");
70 return;
71 }
72 /*@=modfilesys@*/
73
74 static
75 int rpmsslSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
76 /*@modifies dig @*/
77 {
78 rpmssl ssl = dig->impl;
79 unsigned int nbits = BN_num_bits(ssl->c);
80 unsigned int nb = (nbits + 7) >> 3;
81 const char * prefix = rpmDigestASN1(ctx);
82 const char * hexstr;
83 const char * s;
84 rpmuint8_t signhash16[2];
85 char * tt;
86 int xx;
87
88 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
89 if (prefix == NULL)
90 return 1;
91
92 xx = rpmDigestFinal(ctx, (void **)&dig->md5, &dig->md5len, 1);
93 hexstr = tt = xmalloc(2 * nb + 1);
94 memset(tt, (int) 'f', (2 * nb));
95 tt[0] = '0'; tt[1] = '0';
96 tt[2] = '0'; tt[3] = '1';
97 tt += (2 * nb) - strlen(prefix) - strlen(dig->md5) - 2;
98 *tt++ = '0'; *tt++ = '0';
99 tt = stpcpy(tt, prefix);
100 tt = stpcpy(tt, dig->md5);
101
102 /* Set RSA hash. */
103 /*@-moduncon -noeffectuncon @*/
104 xx = BN_hex2bn(&ssl->rsahm, hexstr);
105 /*@=moduncon =noeffectuncon @*/
106
107 /*@-modfilesys@*/
108 if (_pgp_debug < 0) fprintf(stderr, "*** rsahm: %s\n", hexstr);
109 hexstr = _free(hexstr);
110 /*@=modfilesys@*/
111
112 /* Compare leading 16 bits of digest for quick check. */
113 s = dig->md5;
114 /*@-type@*/
115 signhash16[0] = (rpmuint8_t) (nibble(s[0]) << 4) | nibble(s[1]);
116 signhash16[1] = (rpmuint8_t) (nibble(s[2]) << 4) | nibble(s[3]);
117 /*@=type@*/
118 return memcmp(signhash16, sigp->signhash16, sizeof(sigp->signhash16));
119 }
120
121 static unsigned char * rpmsslBN2bin(const char * msg, const BIGNUM * s, size_t maxn)
122 {
123 unsigned char * t = xcalloc(1, maxn);
124 /*@-modunconnomods@*/
125 size_t nt = BN_bn2bin(s, t);
126 /*@=modunconnomods@*/
127
128 if (nt < maxn) {
129 size_t pad = (maxn - nt);
130 /*@-modfilesys@*/
131 if (_pgp_debug < 0) fprintf(stderr, "\tmemmove(%p, %p, %u)\n", t+pad, t, (unsigned)nt);
132 /*@=modfilesys@*/
133 memmove(t+pad, t, nt);
134 /*@-modfilesys@*/
135 if (_pgp_debug < 0) fprintf(stderr, "\tmemset(%p, 0, %u)\n", t, (unsigned)pad);
136 /*@=modfilesys@*/
137 memset(t, 0, pad);
138 }
139 /*@-modfilesys@*/
140 if (_pgp_debug < 0) hexdump(msg, t, maxn);
141 /*@=modfilesys@*/
142 return t;
143 }
144
145 static
146 int rpmsslVerifyRSA(pgpDig dig)
147 /*@*/
148 {
149 rpmssl ssl = dig->impl;
150 /*@-moduncon@*/
151 size_t maxn = BN_num_bytes(ssl->rsa->n);
152 unsigned char * hm = rpmsslBN2bin("hm", ssl->rsahm, maxn);
153 unsigned char * c = rpmsslBN2bin(" c", ssl->c, maxn);
154 size_t nb = RSA_public_decrypt((int)maxn, c, c, ssl->rsa, RSA_PKCS1_PADDING);
155 /*@=moduncon@*/
156 size_t i;
157 int rc = 0;
158 int xx;
159
160 /* Verify RSA signature. */
161 /* XXX This is _NOT_ the correct openssl function to use:
162 * rc = RSA_verify(type, m, m_len, sigbuf, siglen, ssl->rsa)
163 *
164 * Here's what needs doing (from OpenPGP reference sources in 1999):
165 * static u32_t checkrsa(BIGNUM * a, RSA * key, u8_t * hash, int hlen)
166 * {
167 * u8_t dbuf[MAXSIGM];
168 * int j, ll;
169 *
170 * j = BN_bn2bin(a, dbuf);
171 * ll = BN_num_bytes(key->n);
172 * while (j < ll)
173 * memmove(&dbuf[1], dbuf, j++), dbuf[0] = 0;
174 * j = RSA_public_decrypt(ll, dbuf, dbuf, key, RSA_PKCS1_PADDING);
175 * RSA_free(key);
176 * return (j != hlen || memcmp(dbuf, hash, j));
177 * }
178 */
179 for (i = 2; i < maxn; i++) {
180 if (hm[i] == 0xff)
181 continue;
182 i++;
183 /*@-modfilesys@*/
184 if (_pgp_debug < 0) hexdump("HM", hm + i, (maxn - i));
185 /*@=modfilesys@*/
186 break;
187 }
188
189 /*@-modfilesys@*/
190 if (_pgp_debug < 0) hexdump("HM", hm + (maxn - nb), nb);
191 if (_pgp_debug < 0) hexdump(" C", c, nb);
192 /*@=modfilesys@*/
193
194 rc = ((maxn - i) == nb && (xx = memcmp(hm+i, c, nb)) == 0);
195
196 c = _free(c);
197 hm = _free(hm);
198
199 return rc;
200 }
201
202 static
203 int rpmsslSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
204 /*@modifies dig @*/
205 {
206 int xx;
207
208 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
209 /* Set DSA hash. */
210 xx = rpmDigestFinal(ctx, (void **)&dig->sha1, &dig->sha1len, 0);
211
212 /* Compare leading 16 bits of digest for quick check. */
213 return memcmp(dig->sha1, sigp->signhash16, sizeof(sigp->signhash16));
214 }
215
216 static
217 int rpmsslVerifyDSA(pgpDig dig)
218 /*@*/
219 {
220 rpmssl ssl = dig->impl;
221 int rc;
222
223 /* Verify DSA signature. */
224 /*@-moduncon@*/
225 rc = (DSA_do_verify(dig->sha1, (int)dig->sha1len, ssl->dsasig, ssl->dsa) == 1);
226 /*@=moduncon@*/
227
228 return rc;
229 }
230
231
232 static
233 int rpmsslSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
234 /*@*/
235 {
236 int rc = 1; /* XXX always fail. */
237 int xx;
238
239 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
240 xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0);
241
242 /* Compare leading 16 bits of digest for quick check. */
243
244 return rc;
245 }
246
247 static
248 int rpmsslVerifyECDSA(/*@unused@*/pgpDig dig)
249 /*@*/
250 {
251 int rc = 0; /* XXX always fail. */
252
253 return rc;
254 }
255
256 static
257 int rpmsslMpiItem(/*@unused@*/ const char * pre, pgpDig dig, int itemno,
258 const rpmuint8_t * p,
259 /*@unused@*/ /*@null@*/ const rpmuint8_t * pend)
260 /*@*/
261 {
262 rpmssl ssl = dig->impl;
263 unsigned int nb = ((pgpMpiBits(p) + 7) >> 3);
264 int rc = 0;
265
266 /*@-moduncon@*/
267 switch (itemno) {
268 default:
269 assert(0);
270 break;
271 case 10: /* RSA m**d */
272 ssl->c = BN_bin2bn(p+2, nb, ssl->c);
273 break;
274 case 20: /* DSA r */
275 if (ssl->dsasig == NULL) ssl->dsasig = DSA_SIG_new();
276 ssl->dsasig->r = BN_bin2bn(p+2, nb, ssl->dsasig->r);
277 break;
278 case 21: /* DSA s */
279 if (ssl->dsasig == NULL) ssl->dsasig = DSA_SIG_new();
280 ssl->dsasig->s = BN_bin2bn(p+2, nb, ssl->dsasig->s);
281 break;
282 case 30: /* RSA n */
283 if (ssl->rsa == NULL) ssl->rsa = RSA_new();
284 ssl->rsa->n = BN_bin2bn(p+2, nb, ssl->rsa->n);
285 break;
286 case 31: /* RSA e */
287 if (ssl->rsa == NULL) ssl->rsa = RSA_new();
288 ssl->rsa->e = BN_bin2bn(p+2, nb, ssl->rsa->e);
289 break;
290 case 40: /* DSA p */
291 if (ssl->dsa == NULL) ssl->dsa = DSA_new();
292 ssl->dsa->p = BN_bin2bn(p+2, nb, ssl->dsa->p);
293 break;
294 case 41: /* DSA q */
295 if (ssl->dsa == NULL) ssl->dsa = DSA_new();
296 ssl->dsa->q = BN_bin2bn(p+2, nb, ssl->dsa->q);
297 break;
298 case 42: /* DSA g */
299 if (ssl->dsa == NULL) ssl->dsa = DSA_new();
300 ssl->dsa->g = BN_bin2bn(p+2, nb, ssl->dsa->g);
301 break;
302 case 43: /* DSA y */
303 if (ssl->dsa == NULL) ssl->dsa = DSA_new();
304 ssl->dsa->pub_key = BN_bin2bn(p+2, nb, ssl->dsa->pub_key);
305 break;
306 }
307 /*@=moduncon@*/
308 return rc;
309 }
310
311 /*@-mustmod@*/
312 static
313 void rpmsslClean(void * impl)
314 /*@modifies impl @*/
315 {
316 rpmssl ssl = impl;
317 /*@-moduncon@*/
318 if (ssl != NULL) {
319 if (ssl->dsa) {
320 DSA_free(ssl->dsa);
321 ssl->dsa = NULL;
322 }
323 if (ssl->dsasig) {
324 DSA_SIG_free(ssl->dsasig);
325 ssl->dsasig = NULL;
326 }
327 if (ssl->rsa) {
328 RSA_free(ssl->rsa);
329 ssl->rsa = NULL;
330 }
331 if (ssl->c) {
332 BN_free(ssl->c);
333 ssl->c = NULL;
334 }
335 }
336 /*@=moduncon@*/
337 }
338 /*@=mustmod@*/
339
340 static /*@null@*/
341 void * rpmsslFree(/*@only@*/ void * impl)
342 /*@modifies impl @*/
343 {
344 rpmssl ssl = impl;
345 rpmsslClean(impl);
346 ssl = _free(ssl);
347 return NULL;
348 }
349
350 static
351 void * rpmsslInit(void)
352 /*@*/
353 {
354 rpmssl ssl = xcalloc(1, sizeof(*ssl));
355 /*@-moduncon@*/
356 ERR_load_crypto_strings();
357 /*@=moduncon@*/
358 return (void *) ssl;
359 }
360
361 struct pgpImplVecs_s rpmsslImplVecs = {
362 rpmsslSetRSA, rpmsslVerifyRSA,
363 rpmsslSetDSA, rpmsslVerifyDSA,
364 rpmsslSetECDSA, rpmsslVerifyECDSA,
365 rpmsslMpiItem, rpmsslClean,
366 rpmsslFree, rpmsslInit
367 };
368
369 #endif
370