/** \ingroup rpmpgp * Return hex formatted representation of a multiprecision integer. * @param p bytes * @return hex formatted string (malloc'ed) */ static inline char * pgpMpiStr(const uint8_t *p) { char *str = NULL; char *hex = pgpHexStr(p+2, pgpMpiLen(p)-2); rasprintf(&str, "[%4u]: %s", pgpGrab(p, (size_t) 2), hex); free(hex); return str; }
static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num, const uint8_t *p) { BIGNUM *bn; size_t mlen = pgpMpiLen(p) - 2; struct pgpDigKeyDSA_s *key = pgpkey->data; if (!key) { key = pgpkey->data = xcalloc(1, sizeof(*key)); } /* Create a BIGNUM from the key pointer. Note: this assumes big-endian data as required by the PGP multiprecision integer format (RFC4880, Section 3.2) */ bn = BN_bin2bn(p+2, mlen, NULL); if (!bn) return 1; switch (num) { case 0: /* Prime */ if (key->p) { /* This should only ever happen once per key */ return 1; } key->p = bn; break; case 1: /* Subprime */ if (key->q) { /* This should only ever happen once per key */ return 1; } key->q = bn; break; case 2: /* Base */ if (key->g) { /* This should only ever happen once per key */ return 1; } key->g = bn; break; case 3: /* Public */ if (key->y) { /* This should only ever happen once per key */ return 1; } key->y = bn; break; } return 0; }
static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num, const uint8_t *p) { BIGNUM *bn = NULL; int mlen = pgpMpiLen(p) - 2; int rc = 1; struct pgpDigSigDSA_s *sig = pgpsig->data; if (!sig) { sig = xcalloc(1, sizeof(*sig)); } /* Create a BIGNUM from the signature pointer. Note: this assumes big-endian data as required by the PGP multiprecision integer format (RFC4880, Section 3.2) */ bn = BN_bin2bn(p+2, mlen, NULL); if (!bn) return 1; switch (num) { case 0: if (sig->r) { /* This should only ever happen once per signature */ BN_free(bn); return 1; } sig->r = bn; rc = 0; break; case 1: if (sig->s) { /* This should only ever happen once per signature */ BN_free(bn); return 1; } sig->s = bn; rc = 0; break; } pgpsig->data = sig; return rc; }
static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num, const uint8_t *p) { BIGNUM *bn = NULL; int mlen = pgpMpiLen(p) - 2; int rc = 1; struct pgpDigSigRSA_s *sig = pgpsig->data; if (!sig) { sig = xcalloc(1, sizeof(*sig)); } switch (num) { case 0: if (sig->bn) { /* This should only ever happen once per signature */ return 1; } bn = sig->bn = BN_new(); if (!bn) return 1; /* Create a BIGNUM from the signature pointer. Note: this assumes big-endian data as required by the PGP multiprecision integer format (RFC4880, Section 3.2) This will be useful later, as we can retrieve this value with appropriate padding. */ bn = BN_bin2bn(p+2, mlen, bn); if (!bn) return 1; sig->bn = bn; sig->len = mlen; pgpsig->data = sig; rc = 0; break; } return rc; }
static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p) { size_t mlen = pgpMpiLen(p) - 2; struct pgpDigKeyRSA_s *key = pgpkey->data; if (!key) { key = pgpkey->data = xcalloc(1, sizeof(*key)); } switch (num) { case 0: /* Modulus */ if (key->n) { /* This should only ever happen once per key */ return 1; } key->nbytes = mlen; /* Create a BIGNUM from the pointer. Note: this assumes big-endian data as required by PGP */ key->n = BN_bin2bn(p+2, mlen, NULL); if (!key->n) return 1; break; case 1: /* Exponent */ if (key->e) { /* This should only ever happen once per key */ return 1; } /* Create a BIGNUM from the pointer. Note: this assumes big-endian data as required by PGP */ key->e = BN_bin2bn(p+2, mlen, NULL); if (!key->e) return 1; break; } return 0; }