9 #define _RPMPGP_INTERNAL
12 #if defined(__LCLINT__) && !defined(__i386__)
16 #define _RPMSSL_INTERNAL
36 static int _rpmssl_debug;
38 #define SPEW(_t, _rc, _dig) \
39 { if ((_t) || _rpmssl_debug || _pgp_debug < 0) \
40 fprintf(stderr, "<-- %s(%p) %s\t%s\n", __FUNCTION__, (_dig), \
41 ((_rc) ? "OK" : "BAD"), (_dig)->pubkey_algoN); \
44 static const char * rpmsslHashAlgo2Name(uint32_t algo)
49 static const char * rpmsslPubkeyAlgo2Name(uint32_t algo)
63 if (c >=
'0' && c <=
'9')
64 return (
unsigned char) (c -
'0');
65 if (c >=
'A' && c <=
'F')
66 return (
unsigned char)((
int)(c -
'A') + 10);
67 if (c >=
'a' && c <=
'f')
68 return (
unsigned char)((
int)(c -
'a') + 10);
69 return (
unsigned char)
'\0';
72 static unsigned char * rpmsslBN2bin(
const char *
msg,
const BIGNUM *
s,
size_t maxn)
74 unsigned char *
t = (
unsigned char *)
xcalloc(1, maxn);
76 size_t nt = BN_bn2bin(s, t);
80 size_t pad = (maxn - nt);
81 memmove(t+pad, t, nt);
92 unsigned int nb = RSA_size(ssl->rsa);
101 dig->pubkey_algoN = rpmsslPubkeyAlgo2Name(pubp->pubkey_algo);
102 dig->hash_algoN = rpmsslHashAlgo2Name(sigp->hash_algo);
109 ssl->digest =
_free(ssl->digest);
111 xx =
rpmDigestFinal(ctx, (
void **)&ssl->digest, &ssl->digestlen, 1);
113 hexstr = tt = (
char *)
xmalloc(2 *
nb + 1);
115 tt[0] =
'0'; tt[1] =
'0';
116 tt[2] =
'0'; tt[3] =
'1';
117 tt += (2 *
nb) - strlen(prefix) - strlen((
const char *)ssl->digest) - 2;
118 *tt++ =
'0'; *tt++ =
'0';
120 tt =
stpcpy(tt, (
const char *)ssl->digest);
124 xx = BN_hex2bn(&ssl->hm, hexstr);
129 hexstr =
_free(hexstr);
133 s = (
const char *) ssl->digest;
138 rc = memcmp(signhash16, sigp->signhash16,
sizeof(sigp->signhash16));
145 int rpmsslVerifyRSA(
pgpDig dig)
160 maxn = BN_num_bytes(ssl->rsa->n);
161 hm = rpmsslBN2bin(
"hm", ssl->hm, maxn);
162 c = rpmsslBN2bin(
" c", ssl->c, maxn);
163 nb = RSA_public_decrypt((
int)maxn, c, c, ssl->rsa, RSA_PKCS1_PADDING);
185 for (
i = 2;
i < maxn;
i++) {
192 rc = ((maxn -
i) ==
nb && (xx = memcmp(hm+
i, c,
nb)) == 0);
202 int rpmsslSignRSA(
pgpDig dig)
207 unsigned char * c =
NULL;
208 unsigned char * hm =
NULL;
215 if (ssl->rsa ==
NULL)
return rc;
218 maxn = RSA_size(ssl->rsa);
220 hm = rpmsslBN2bin(
"hm", ssl->hm, maxn);
222 c = (
unsigned char *)
xmalloc(maxn);
223 xx = RSA_private_encrypt((
int)maxn, hm, c, ssl->rsa, RSA_NO_PADDING);
224 ssl->c = BN_bin2bn(c, maxn,
NULL);
229 rc = (ssl->c !=
NULL);
237 int rpmsslGenerateRSA(
pgpDig dig)
242 static unsigned long _e = 0x10001;
244 if (ssl->nbits == 0) ssl->nbits = 1024;
247 #if defined(HAVE_RSA_GENERATE_KEY_EX)
248 { BIGNUM * bn = BN_new();
250 if ((ssl->rsa = RSA_new()) !=
NULL
251 && BN_set_word(bn, _e)
252 && RSA_generate_key_ex(ssl->rsa, ssl->nbits, bn,
NULL))
258 if ((ssl->rsa = RSA_generate_key(ssl->nbits, _e,
NULL,
NULL)) !=
NULL)
262 if (!rc && ssl->rsa) {
280 dig->pubkey_algoN = rpmsslPubkeyAlgo2Name(pubp->pubkey_algo);
281 dig->hash_algoN = rpmsslHashAlgo2Name(sigp->hash_algo);
286 ssl->digest =
_free(ssl->digest);
288 xx =
rpmDigestFinal(ctx, (
void **)&ssl->digest, &ssl->digestlen, 0);
291 rc = memcmp(ssl->digest, sigp->signhash16,
sizeof(sigp->signhash16));
297 int rpmsslVerifyDSA(
pgpDig dig)
305 rc = DSA_do_verify((
const unsigned char *)ssl->digest, (
int)ssl->digestlen, ssl->dsasig, ssl->dsa);
313 int rpmsslSignDSA(
pgpDig dig)
322 if (ssl->dsa ==
NULL)
return rc;
325 ssl->dsasig = DSA_do_sign((
const unsigned char *)ssl->digest, ssl->digestlen, ssl->dsa);
326 rc = (ssl->dsasig !=
NULL);
334 int rpmsslGenerateDSA(
pgpDig dig)
340 if (ssl->nbits == 0) ssl->nbits = 1024;
343 #if defined(HAVE_DSA_GENERATE_PARAMETERS_EX)
344 if ((ssl->dsa = DSA_new()) !=
NULL
345 && DSA_generate_parameters_ex(ssl->dsa, ssl->nbits,
347 && DSA_generate_key(ssl->dsa))
351 if ((ssl->dsa = DSA_generate_parameters(ssl->nbits,
353 && DSA_generate_key(ssl->dsa))
357 if (!rc && ssl->dsa) {
378 ssl->digest =
_free(ssl->digest);
380 xx =
rpmDigestFinal(ctx, (
void **)&ssl->digest, &ssl->digestlen, 0);
400 ssl->digest =
_free(ssl->digest);
412 int rpmsslVerifyECDSA(
pgpDig dig)
417 #if !defined(OPENSSL_NO_ECDSA)
419 rc = ECDSA_do_verify(ssl->digest, ssl->digestlen, ssl->ecdsasig, ssl->ecdsakey);
428 int rpmsslSignECDSA(
pgpDig dig)
433 #if !defined(OPENSSL_NO_ECDSA)
435 ssl->ecdsasig = ECDSA_do_sign(ssl->digest, ssl->digestlen, ssl->ecdsakey);
436 rc = (ssl->ecdsasig !=
NULL);
444 int rpmsslGenerateECDSA(
pgpDig dig)
449 #if !defined(OPENSSL_NO_ECDSA)
453 ssl->nid = NID_X9_62_prime256v1;
457 if ((ssl->ecdsakey = EC_KEY_new_by_curve_name(ssl->nid)) !=
NULL
458 && EC_KEY_generate_key(ssl->ecdsakey))
466 static int rpmsslErrChk(
pgpDig dig,
const char * msg,
int rc,
unsigned expected)
469 rpmgc gc = dig->impl;
471 rc = (gcry_err_code(gc->err) != expected);
473 fail(
"%s failed: %s\n", msg, gpg_strerror(gc->err));
481 static int rpmsslAvailableCipher(
pgpDig dig,
int algo)
485 rc = rpmgsslvailable(dig->impl, algo,
491 static int rpmsslAvailableDigest(
pgpDig dig,
int algo)
495 rc = rpmgsslvailable(dig->impl, algo,
501 static int rpmsslAvailablePubkey(
pgpDig dig,
int algo)
505 rc = rpmsslAvailable(dig->impl, algo, gcry_pk_test_algo(algo));
510 static int rpmsslVerify(
pgpDig dig)
515 dig->pubkey_algoN = rpmsslPubkeyAlgo2Name(pubp->pubkey_algo);
516 dig->hash_algoN = rpmsslHashAlgo2Name(sigp->hash_algo);
518 switch (pubp->pubkey_algo) {
522 rc = rpmsslVerifyRSA(dig);
525 rc = rpmsslVerifyDSA(dig);
529 rc = rpmsslVerifyELG(dig);
533 rc = rpmsslVerifyECDSA(dig);
540 static int rpmsslSign(
pgpDig dig)
544 dig->pubkey_algoN = rpmsslPubkeyAlgo2Name(pubp->pubkey_algo);
546 switch (pubp->pubkey_algo) {
550 rc = rpmsslSignRSA(dig);
553 rc = rpmsslSignDSA(dig);
557 rc = rpmsslSignELG(dig);
561 rc = rpmsslSignECDSA(dig);
568 static int rpmsslGenerate(
pgpDig dig)
572 dig->pubkey_algoN = rpmsslPubkeyAlgo2Name(pubp->pubkey_algo);
574 switch (pubp->pubkey_algo) {
578 rc = rpmsslGenerateRSA(dig);
581 rc = rpmsslGenerateDSA(dig);
585 rc = rpmsslGenerateELG(dig);
589 rc = rpmsslGenerateECDSA(dig);
597 int rpmsslMpiItem(
const char * pre,
pgpDig dig,
int itemno,
616 ssl->c = BN_bin2bn(p+2,
nb, ssl->c);
619 if (ssl->dsasig ==
NULL) ssl->dsasig = DSA_SIG_new();
620 ssl->dsasig->r = BN_bin2bn(p+2,
nb, ssl->dsasig->r);
623 if (ssl->dsasig ==
NULL) ssl->dsasig = DSA_SIG_new();
624 ssl->dsasig->s = BN_bin2bn(p+2,
nb, ssl->dsasig->s);
627 if (ssl->rsa ==
NULL) ssl->rsa = RSA_new();
628 ssl->rsa->n = BN_bin2bn(p+2,
nb, ssl->rsa->n);
631 if (ssl->rsa ==
NULL) ssl->rsa = RSA_new();
632 ssl->rsa->e = BN_bin2bn(p+2,
nb, ssl->rsa->e);
635 if (ssl->dsa ==
NULL) ssl->dsa = DSA_new();
636 ssl->dsa->p = BN_bin2bn(p+2,
nb, ssl->dsa->p);
639 if (ssl->dsa ==
NULL) ssl->dsa = DSA_new();
640 ssl->dsa->q = BN_bin2bn(p+2,
nb, ssl->dsa->q);
643 if (ssl->dsa ==
NULL) ssl->dsa = DSA_new();
644 ssl->dsa->g = BN_bin2bn(p+2,
nb, ssl->dsa->g);
647 if (ssl->dsa ==
NULL) ssl->dsa = DSA_new();
648 ssl->dsa->pub_key = BN_bin2bn(p+2,
nb, ssl->dsa->pub_key);
657 void rpmsslClean(
void * impl)
666 ssl->digest =
_free(ssl->digest);
673 DSA_SIG_free(ssl->dsasig);
686 #if !defined(OPENSSL_NO_ECDSA)
688 EC_KEY_free(ssl->ecdsakey);
689 ssl->ecdsakey =
NULL;
691 ECDSA_SIG_free(ssl->ecdsasig);
692 ssl->ecdsasig =
NULL;
694 if (ssl->ecdsakey_bad)
695 EC_KEY_free(ssl->ecdsakey_bad);
696 ssl->ecdsakey_bad =
NULL;
705 void * rpmsslFree(
void * impl)
714 void * rpmsslInit(
void)
719 ERR_load_crypto_strings();
731 rpmsslAvailableCipher, rpmsslAvailableDigest, rpmsslAvailablePubkey,
732 rpmsslVerify, rpmsslSign, rpmsslGenerate,
734 rpmsslMpiItem, rpmsslClean,
735 rpmsslFree, rpmsslInit
static unsigned int pgpMpiBits(const rpmuint8_t *p)
Return no.
static char *size_t nb
fgets(3) analogue that reads \ continuations.
static unsigned char nibble(char c)
Convert hex to binary nibble.
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
Yet Another syslog(3) API clone.
memset(_r, 0, sizeof(*_r))
void * xcalloc(size_t nmemb, size_t size)
assert(key->size==sizeof(hdrNum))
struct pgpValTbl_s pgpHashTbl[]
Hash (string, value) pairs.
fprintf(stderr,"--> %s(%p,%p,%p) sig %p sigp %p\n", __FUNCTION__, dig, t, rsactx, sig, sigp)
pgpDigParams pgpGetSignature(pgpDig dig)
Return OpenPGP signature parameters.
pgpHashAlgo rpmDigestAlgo(DIGEST_CTX ctx)
Return digest algorithm identifier.
pgpImplVecs_t rpmsslImplVecs
Implementation specific parameter storage.
static const char *char c
Return text between pl and matching pr characters.
static const char * prefix[]
Tables for prefixing and suffixing patterns, according to the -w, -x, and -F options.
char * stpcpy(char *dest, const char *src)
#define SPEW(_t, _rc, _dig)
struct pgpDigParams_s * pgpDigParams
static const char * pgpValStr(pgpValTbl vs, rpmuint8_t val)
Return string representation of am OpenPGP value.
int
Save source and expand field into target.
void rpmDigestFinal(rpmDigestDup(md5ctx),&md5sum,&md5len, 0)
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
const char * rpmDigestASN1(DIGEST_CTX ctx)
Return digest ASN1 oid string.
pgpDigParams pgpGetPubkey(pgpDig dig)
Return OpenPGP pubkey parameters.
struct pgpValTbl_s pgpPubkeyTbl[]