rpm  5.2.1
rpmbc.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 #define _RPMBC_INTERNAL
7 #define _RPMPGP_INTERNAL
8 #include <rpmbc.h>
9 #include "debug.h"
10 
11 /*@access pgpDig @*/
12 /*@access pgpDigParams @*/
13 
14 /*@-redecl@*/
15 /*@unchecked@*/
16 extern int _pgp_debug;
17 
18 /*@unchecked@*/
19 extern int _pgp_print;
20 /*@=redecl@*/
21 
27 static
28 unsigned char nibble(char c)
29  /*@*/
30 {
31  if (c >= '0' && c <= '9')
32  return (unsigned char) (c - '0');
33  if (c >= 'A' && c <= 'F')
34  return (unsigned char)((int)(c - 'A') + 10);
35  if (c >= 'a' && c <= 'f')
36  return (unsigned char)((int)(c - 'a') + 10);
37  return (unsigned char) '\0';
38 }
39 
40 static
41 int rpmbcSetRSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
42  /*@modifies dig @*/
43 {
44  rpmbc bc = dig->impl;
45  unsigned int nbits = (unsigned) MP_WORDS_TO_BITS(bc->c.size);
46  unsigned int nb = (nbits + 7) >> 3;
47  const char * prefix = rpmDigestASN1(ctx);
48  const char * hexstr;
49  char * tt;
50  int rc;
51  int xx;
52 
53 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
54  if (prefix == NULL)
55  return 1;
56 
57  xx = rpmDigestFinal(ctx, (void **)&dig->md5, &dig->md5len, 1);
58  hexstr = tt = xmalloc(2 * nb + 1);
59  memset(tt, (int) 'f', (2 * nb));
60  tt[0] = '0'; tt[1] = '0';
61  tt[2] = '0'; tt[3] = '1';
62  tt += (2 * nb) - strlen(prefix) - strlen(dig->md5) - 2;
63  *tt++ = '0'; *tt++ = '0';
64  tt = stpcpy(tt, prefix);
65  tt = stpcpy(tt, dig->md5);
66 
67 /*@-moduncon -noeffectuncon @*/
68  mpnzero(&bc->rsahm); (void) mpnsethex(&bc->rsahm, hexstr);
69 /*@=moduncon =noeffectuncon @*/
70 
71  hexstr = _free(hexstr);
72 
73  /* Compare leading 16 bits of digest for quick check. */
74  { const char *str = dig->md5;
75  rpmuint8_t s[2];
76  const rpmuint8_t *t = sigp->signhash16;
77  s[0] = (rpmuint8_t) (nibble(str[0]) << 4) | nibble(str[1]);
78  s[1] = (rpmuint8_t) (nibble(str[2]) << 4) | nibble(str[3]);
79  rc = memcmp(s, t, sizeof(sigp->signhash16));
80 #ifdef DYING
81  if (rc != 0)
82  fprintf(stderr, "*** hash fails: digest(%02x%02x) != signhash(%02x%02x)\n",
83  s[0], s[1], t[0], t[1]);
84 #endif
85  }
86  return rc;
87 }
88 
89 static
91  /*@*/
92 {
93  rpmbc bc = dig->impl;
94  int rc;
95 
96 /*@-moduncon@*/
97 #if defined(HAVE_BEECRYPT_API_H)
98  rc = rsavrfy(&bc->rsa_pk.n, &bc->rsa_pk.e, &bc->c, &bc->rsahm);
99 #else
100  rc = rsavrfy(&bc->rsa_pk, &bc->rsahm, &bc->c);
101 #endif
102 /*@=moduncon@*/
103 
104  return rc;
105 }
106 
107 static
108 int rpmbcSetDSA(/*@only@*/ DIGEST_CTX ctx, pgpDig dig, pgpDigParams sigp)
109  /*@modifies dig @*/
110 {
111  rpmbc bc = dig->impl;
112  rpmuint8_t signhash16[2];
113  int xx;
114 
115 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
116  xx = rpmDigestFinal(ctx, (void **)&dig->sha1, &dig->sha1len, 1);
117 
118 /*@-moduncon -noeffectuncon @*/
119  mpnzero(&bc->hm); (void) mpnsethex(&bc->hm, dig->sha1);
120 /*@=moduncon =noeffectuncon @*/
121 
122  /* Compare leading 16 bits of digest for quick check. */
123  signhash16[0] = (rpmuint8_t)((*bc->hm.data >> 24) & 0xff);
124  signhash16[1] = (rpmuint8_t)((*bc->hm.data >> 16) & 0xff);
125  return memcmp(signhash16, sigp->signhash16, sizeof(signhash16));
126 }
127 
128 static
130  /*@*/
131 {
132  rpmbc bc = dig->impl;
133  int rc;
134 
135 /*@-moduncon@*/
136  rc = dsavrfy(&bc->p, &bc->q, &bc->g, &bc->hm, &bc->y, &bc->r, &bc->s);
137 /*@=moduncon@*/
138 
139  return rc;
140 }
141 
142 static
143 int rpmbcSetECDSA(/*@only@*/ DIGEST_CTX ctx, /*@unused@*/pgpDig dig, pgpDigParams sigp)
144  /*@*/
145 {
146  int rc = 1; /* XXX always fail. */
147  int xx;
148 
149 assert(sigp->hash_algo == rpmDigestAlgo(ctx));
150  xx = rpmDigestFinal(ctx, (void **)NULL, NULL, 0);
151 
152  /* Compare leading 16 bits of digest for quick check. */
153 
154  return rc;
155 }
156 
157 static
158 int rpmbcVerifyECDSA(/*@unused@*/pgpDig dig)
159  /*@*/
160 {
161  int rc = 0; /* XXX always fail. */
162 
163  return rc;
164 }
165 
168 static /*@observer@*/
169 const char * pgpMpiHex(const rpmuint8_t *p)
170  /*@*/
171 {
172  static char prbuf[2048];
173  char *t = prbuf;
174  t = pgpHexCvt(t, p+2, pgpMpiLen(p)-2);
175  return prbuf;
176 }
177 
181 static
182 int pgpMpiSet(const char * pre, unsigned int lbits,
183  /*@out@*/ void * dest, const rpmuint8_t * p,
184  /*@null@*/ const rpmuint8_t * pend)
185  /*@globals fileSystem @*/
186  /*@modifies fileSystem @*/
187 {
188  mpnumber * mpn = dest;
189  unsigned int mbits = pgpMpiBits(p);
190  unsigned int nbits;
191  unsigned int nbytes;
192  char * t;
193  unsigned int ix;
194 
195  if (pend != NULL && (p + ((mbits+7) >> 3)) > pend)
196  return 1;
197 
198  if (mbits > lbits)
199  return 1;
200 
201  nbits = (lbits > mbits ? lbits : mbits);
202  nbytes = ((nbits + 7) >> 3);
203  t = xmalloc(2*nbytes+1);
204  ix = 2 * ((nbits - mbits) >> 3);
205 
206 if (_pgp_debug)
207 fprintf(stderr, "*** mbits %u nbits %u nbytes %u t %p[%d] ix %u\n", mbits, nbits, nbytes, t, (2*nbytes+1), ix);
208  if (ix > 0) memset(t, (int)'0', ix);
209  strcpy(t+ix, (const char *) pgpMpiHex(p));
210 if (_pgp_debug)
211 fprintf(stderr, "*** %s %s\n", pre, t);
212  (void) mpnsethex(mpn, t);
213  t = _free(t);
214 if (_pgp_debug && _pgp_print)
215 fprintf(stderr, "\t %s ", pre), mpfprintln(stderr, mpn->size, mpn->data);
216  return 0;
217 }
218 
219 static
220 int rpmbcMpiItem(const char * pre, pgpDig dig, int itemno,
221  const rpmuint8_t * p, /*@null@*/ const rpmuint8_t * pend)
222  /*@globals fileSystem @*/
223  /*@modifies fileSystem @*/
224 {
225  rpmbc bc = dig->impl;
226  int rc = 0;
227 
228  switch (itemno) {
229  default:
230 assert(0);
231  break;
232  case 10: /* RSA m**d */
233  (void) mpnsethex(&bc->c, pgpMpiHex(p));
234 if (_pgp_debug && _pgp_print)
235 fprintf(stderr, "\t %s ", pre), mpfprintln(stderr, bc->c.size, bc->c.data);
236  break;
237  case 20: /* DSA r */
238  rc = pgpMpiSet(pre, 160, &bc->r, p, pend);
239  break;
240  case 21: /* DSA s */
241  rc = pgpMpiSet(pre, 160, &bc->s, p, pend);
242  break;
243  case 30: /* RSA n */
244  (void) mpbsethex(&bc->rsa_pk.n, pgpMpiHex(p));
245 if (_pgp_debug && _pgp_print)
246 fprintf(stderr, "\t %s ", pre), mpfprintln(stderr, bc->rsa_pk.n.size, bc->rsa_pk.n.modl);
247  break;
248  case 31: /* RSA e */
249  (void) mpnsethex(&bc->rsa_pk.e, pgpMpiHex(p));
250 if (_pgp_debug && _pgp_print)
251 fprintf(stderr, "\t %s ", pre), mpfprintln(stderr, bc->rsa_pk.e.size, bc->rsa_pk.e.data);
252  break;
253  case 40: /* DSA p */
254  (void) mpbsethex(&bc->p, pgpMpiHex(p));
255 if (_pgp_debug && _pgp_print)
256 fprintf(stderr, "\t %s ", pre), mpfprintln(stderr, bc->p.size, bc->p.modl);
257  break;
258  case 41: /* DSA q */
259  (void) mpbsethex(&bc->q, pgpMpiHex(p));
260 if (_pgp_debug && _pgp_print)
261 fprintf(stderr, "\t %s ", pre), mpfprintln(stderr, bc->q.size, bc->q.modl);
262  break;
263  case 42: /* DSA g */
264  (void) mpnsethex(&bc->g, pgpMpiHex(p));
265 if (_pgp_debug && _pgp_print)
266 fprintf(stderr, "\t %s ", pre), mpfprintln(stderr, bc->g.size, bc->g.data);
267  break;
268  case 43: /* DSA y */
269  (void) mpnsethex(&bc->y, pgpMpiHex(p));
270 if (_pgp_debug && _pgp_print)
271 fprintf(stderr, "\t %s ", pre), mpfprintln(stderr, bc->y.size, bc->y.data);
272  break;
273  }
274  return rc;
275 }
276 
277 /*@-mustmod@*/
278 static
279 void rpmbcClean(void * impl)
280  /*@modifies impl @*/
281 {
282  rpmbc bc = impl;
283  if (bc != NULL) {
284  mpnfree(&bc->hm);
285  mpnfree(&bc->r);
286  mpnfree(&bc->s);
287  (void) rsapkFree(&bc->rsa_pk);
288  mpnfree(&bc->m);
289  mpnfree(&bc->c);
290  mpnfree(&bc->rsahm);
291  }
292 }
293 /*@=mustmod@*/
294 
295 static /*@null@*/
296 void * rpmbcFree(/*@only@*/ void * impl)
297  /*@modifies impl @*/
298 {
299  rpmbc bc = impl;
300  if (bc != NULL) {
301  mpbfree(&bc->p);
302  mpbfree(&bc->q);
303  mpnfree(&bc->g);
304  mpnfree(&bc->y);
305  mpnfree(&bc->hm);
306  mpnfree(&bc->r);
307  mpnfree(&bc->s);
308 
309  mpbfree(&bc->rsa_pk.n);
310  mpnfree(&bc->rsa_pk.e);
311  mpnfree(&bc->m);
312  mpnfree(&bc->c);
313  mpnfree(&bc->hm);
314  bc = _free(bc);
315  }
316  return NULL;
317 }
318 
319 static
320 void * rpmbcInit(void)
321  /*@*/
322 {
323  rpmbc bc = xcalloc(1, sizeof(*bc));
324  return (void *) bc;
325 }
326 
333 };