9 #define _RPMGC_INTERNAL
10 #if defined(WITH_GCRYPT)
11 #define _RPMPGP_INTERNAL
17 #if defined(WITH_GCRYPT)
31 static int _rpmgc_debug;
33 #define SPEW(_t, _rc, _dig) \
34 { if ((_t) || _rpmgc_debug || _pgp_debug < 0) \
35 fprintf(stderr, "<-- %s(%p) %s\t%s\n", __FUNCTION__, (_dig), \
36 ((_rc) ? "OK" : "BAD"), (_dig)->pubkey_algoN); \
44 make_flagged_int(
unsigned long value,
unsigned char *
b,
size_t nb)
53 for (more = 0, shift = 28; shift > 0; shift -= 7) {
54 if (more || value >= (1UL << shift)) {
55 b[nb++] = 0x80 | (value >> shift);
56 value -= (value >> shift) << shift;
74 int openpgp_oid_from_str(
const char *
s, gcry_mpi_t * r_mpi)
77 size_t ns = (s ? strlen(s) : 0);
78 unsigned char *
b =
xmalloc(ns + 2 + 1);
82 unsigned long val1 = 0;
88 if (s ==
NULL || s[0] ==
'\0')
93 val = strtoul(se, (
char **) &endp, 10);
94 if (!
xisdigit(*se) || !(*endp ==
'.' || *endp ==
'\0'))
110 b[nb++] = val1 * 40 +
val;
113 nb = make_flagged_int(val, b, nb);
117 nb = make_flagged_int(val, b, nb);
120 }
while (*endp ==
'.');
122 if (arcno == 1 || nb < 2 || nb > 254)
126 *r_mpi = gcry_mpi_set_opaque(
NULL, b, nb * 8);
141 char *openpgp_oid_to_str(gcry_mpi_t a)
143 unsigned int nbits = 0;
144 const unsigned char * b = (a && gcry_mpi_get_flag(a, GCRYMPI_FLAG_OPAQUE))
145 ? gcry_mpi_get_opaque(a, &nbits)
147 size_t nb = (nbits + 7) / 8;
149 size_t nt = (2 + ((nb ? nb-1 : 0) * (3+1)) + 1);
153 unsigned long valmask = (
unsigned long) 0xfe << (8 * (
sizeof(valmask) - 1));
159 if (b ==
NULL || nb == 0 || *b++ != --nb)
164 te +=
sprintf(te,
"0.%d", b[ix]);
166 te +=
sprintf(te,
"1.%d", b[ix] - 40);
169 while ((b[ix] & 0x80) && ++ix < nb) {
176 te +=
sprintf(te,
"2.%lu", val);
181 for (ix++; ix <
nb; ix++) {
183 while ((b[ix] & 0x80) && ++ix < nb) {
189 te +=
sprintf(te,
".%lu", val);
203 t =
xstrdup(
"1.3.6.1.4.1.11591.2.12242973");
217 static const char * rpmgcHashAlgo2Name(uint32_t algo)
222 static const char * rpmgcPubkeyAlgo2Name(uint32_t algo)
227 static void fail(
const char *
format, ...)
231 va_start(arg_ptr, format);
232 vfprintf(stderr, format, arg_ptr);
238 void rpmgcDump(
const char *
msg, gcry_sexp_t sexp)
242 size_t nb = gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED,
NULL, 0);
245 nb = gcry_sexp_sprint(sexp, GCRYSEXP_FMT_ADVANCED, buf, nb);
247 fprintf(stderr,
"========== %s:\n%s", msg, buf);
253 gcry_error_t rpmgcErr(
rpmgc gc,
const char * msg, gcry_error_t err)
257 if (err && gcry_err_code(err) != gc->badok)
258 fprintf (stderr,
"rpmgc: %s(0x%0x): %s/%s\n",
259 msg, (
unsigned)err, gcry_strsource(err), gcry_strerror(err));
269 const char * hash_algo_name =
NULL;
273 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
274 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
276 switch (sigp->hash_algo) {
278 hash_algo_name =
"md5";
281 hash_algo_name =
"sha1";
284 hash_algo_name =
"ripemd160";
287 hash_algo_name =
"md2";
290 hash_algo_name =
"tiger";
294 hash_algo_name =
"haval";
298 hash_algo_name =
"sha256";
301 hash_algo_name =
"sha384";
304 hash_algo_name =
"sha512";
308 hash_algo_name =
"sha224";
314 if (hash_algo_name ==
NULL)
321 err = rpmgcErr(gc,
"RSA c",
322 gcry_sexp_build(&gc->hash,
NULL,
323 "(data (flags pkcs1) (hash %s %b))", hash_algo_name, gc->digestlen, gc->digest) );
324 if (
_pgp_debug < 0) rpmgcDump(
"gc->hash", gc->hash);
329 rc = memcmp(s, t,
sizeof(sigp->signhash16));
350 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
351 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
358 { gcry_mpi_t
c =
NULL;
360 err = rpmgcErr(gc,
"DSA c",
361 gcry_mpi_scan(&c, GCRYMPI_FMT_USG, gc->digest, 160/8,
NULL));
362 err = rpmgcErr(gc,
"DSA gc->hash",
363 gcry_sexp_build(&gc->hash,
NULL,
364 "(data (flags raw) (value %m))", c) );
366 if (
_pgp_debug < 0) rpmgcDump(
"gc->hash", gc->hash);
371 rc = memcmp(gc->digest, sigp->signhash16,
sizeof(sigp->signhash16));
385 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
386 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
393 { gcry_mpi_t c =
NULL;
395 err = rpmgcErr(gc,
"ELG c",
396 gcry_mpi_scan(&c, GCRYMPI_FMT_USG, gc->digest, 160/8,
NULL));
397 err = rpmgcErr(gc,
"ELG gc->hash",
398 gcry_sexp_build(&gc->hash,
NULL,
399 "(data (flags raw) (value %m))", c) );
401 if (1 ||
_pgp_debug < 0) rpmgcDump(
"gc->hash", gc->hash);
406 rc = memcmp(gc->digest, sigp->signhash16,
sizeof(sigp->signhash16));
421 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
422 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
425 gc->digest =
_free(gc->digest);
430 { gcry_mpi_t c =
NULL;
431 err = rpmgcErr(gc,
"ECDSA c",
432 gcry_mpi_scan(&c, GCRYMPI_FMT_USG, gc->digest, gc->digestlen,
NULL));
434 gcry_sexp_release(gc->hash); gc->hash =
NULL;
436 err = rpmgcErr(gc,
"ECDSA gc->hash",
437 gcry_sexp_build(&gc->hash,
NULL,
438 "(data (flags raw) (value %m))", c) );
440 if (
_pgp_debug < 0) rpmgcDump(
"gc->hash", gc->hash);
444 rc = memcmp(gc->digest, sigp->signhash16,
sizeof(sigp->signhash16));
450 static int rpmgcErrChk(
pgpDig dig,
const char * msg,
int rc,
unsigned expected)
454 rc = (gcry_err_code(gc->err) != expected);
456 fail(
"%s failed: %s\n", msg, gpg_strerror(gc->err));
461 static int rpmgcAvailable(
rpmgc gc,
int algo,
int rc)
464 if (rc && !gc->in_fips_mode)
472 fprintf(stderr,
" algorithm %d not available in fips mode\n", algo);
477 static int rpmgcAvailableCipher(
pgpDig dig,
int algo)
480 return rpmgcAvailable(gc, algo, gcry_cipher_test_algo(algo));
483 static int rpmgcAvailableDigest(
pgpDig dig,
int algo)
487 rc = rpmgcAvailable(gc, algo,
492 static int rpmgcAvailablePubkey(
pgpDig dig,
int algo)
496 rc = rpmgcAvailable(gc, algo, gcry_pk_test_algo(algo));
500 static char * _curve_nist =
"NIST P-256";
501 static char * _curve_oid =
"1.2.840.10045.3.1.7";
502 static char * _curve_x962 =
"prime256v1";
503 static char * _curve_secp =
"secp256r1";
506 int rpmgcVerify(
pgpDig dig)
512 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
513 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
515 if (gc->sig ==
NULL) {
517 switch (pubp->pubkey_algo) {
520 gc->err = rpmgcErr(gc,
"RSA gc->sig",
521 gcry_sexp_build(&gc->sig,
NULL,
522 "(sig-val (RSA (s %m)))", gc->c) );
527 gc->err = rpmgcErr(gc,
"DSA gc->sig",
528 gcry_sexp_build(&gc->sig,
NULL,
529 "(sig-val (DSA (r %m) (s %m)))", gc->r, gc->s) );
534 gc->err = rpmgcErr(gc,
"ELG gc->sig",
535 gcry_sexp_build(&gc->sig,
NULL,
536 "(sig-val (ELG (r %m) (s %m)))", gc->r, gc->s) );
541 gc->err = rpmgcErr(gc,
"ECDSA gc->sig",
542 gcry_sexp_build(&gc->sig,
NULL,
543 "(sig-val (ECDSA (r %m) (s %m)))", gc->r, gc->s) );
550 rpmgcDump(
"gc->sig", gc->sig);
553 if (gc->pub_key ==
NULL) {
555 switch (pubp->pubkey_algo) {
563 gc->err = rpmgcErr(gc,
"RSA gc->pub_key",
564 gcry_sexp_build(&gc->pub_key,
NULL,
565 "(public-key (RSA (n %m) (e %m)))", gc->n, gc->e) );
573 gc->err = rpmgcErr(gc,
"DSA gc->pub_key",
574 gcry_sexp_build(&gc->pub_key,
NULL,
575 "(public-key (DSA (p %m) (q %m) (g %m) (y %m)))",
576 gc->p, gc->q, gc->g, gc->y) );
583 gc->err = rpmgcErr(gc,
"ELG gc->pub_key",
584 gcry_sexp_build(&gc->pub_key,
NULL,
585 "(public-key (ELG (p %m) (g %m) (y %m)))",
586 gc->p, gc->g, gc->y) );
597 {
unsigned int nbits = 0;
598 rpmuint8_t * b = gcry_mpi_get_opaque(gc->o, &nbits);
599 size_t nb = (nbits+7)/8;
602 t = openpgp_oid_to_str(gc->o);
606 gc->err = rpmgcErr(gc,
"ECDSA gc->pub_key",
607 gcry_sexp_build(&gc->pub_key,
NULL,
608 "(public-key (ECDSA (curve \"%s\") (q %m))",
609 _curve_x962, gc->q) );
616 rpmgcDump(
"gc->pub_key", gc->pub_key);
620 gc->err = rpmgcErr(gc,
"gcry_pk_verify",
621 gcry_pk_verify (gc->sig, gc->hash, gc->pub_key));
636 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
637 dig->hash_algoN = rpmgcHashAlgo2Name(sigp->hash_algo);
640 gc->err = rpmgcErr(gc,
"gcry_pk_sign",
641 gcry_pk_sign (&gc->sig, gc->hash, gc->sec_key));
643 if (_pgp_debug < 0 && gc->sig) rpmgcDump(
"gc->sig", gc->sig);
652 int rpmgcGenerate(
pgpDig dig)
658 dig->pubkey_algoN = rpmgcPubkeyAlgo2Name(pubp->pubkey_algo);
662 switch (pubp->pubkey_algo) {
664 if (gc->nbits == 0) gc->nbits = 1024;
665 gc->err = rpmgcErr(gc,
"gc->key_spec",
666 gcry_sexp_build(&gc->key_spec,
NULL,
668 ?
"(genkey (RSA (nbits %d)))"
669 :
"(genkey (RSA (nbits %d)(transient-key)))",
673 if (gc->nbits == 0) gc->nbits = 1024;
674 gc->err = rpmgcErr(gc,
"gc->key_spec",
675 gcry_sexp_build(&gc->key_spec,
NULL,
677 ?
"(genkey (DSA (nbits %d)))"
678 :
"(genkey (DSA (nbits %d)(transient-key)))",
682 if (gc->nbits == 0) gc->nbits = 1024;
683 gc->err = rpmgcErr(gc,
"gc->key_spec",
684 gcry_sexp_build(&gc->key_spec,
NULL,
686 ?
"(genkey (ELG (nbits %d)))"
687 :
"(genkey (ELG (nbits %d)(transient-key)))",
691 if (gc->nbits == 0) gc->nbits = 256;
693 gc->err = rpmgcErr(gc,
"gc->key_spec",
694 gcry_sexp_build(&gc->key_spec,
NULL,
696 ?
"(genkey (ECDSA (nbits %d)))"
697 :
"(genkey (ECDSA (nbits %d)(transient-key)))",
701 {
char * t =
rpmExpand(
"(genkey (ECDSA (curve \"", _curve_nist,
"\")",
702 gc->in_fips_mode ?
"" :
"(transient-key)",
704 gc->err = rpmgcErr(gc,
"gc->key_spec",
705 gcry_sexp_build(&gc->key_spec,
NULL, t));
716 if ((_rpmgc_debug ||
_pgp_debug < 0) && gc->key_spec) rpmgcDump(
"gc->key_spec", gc->key_spec);
719 gc->err = rpmgcErr(gc,
"gc->key_pair",
720 gcry_pk_genkey(&gc->key_pair, gc->key_spec));
723 if ((_rpmgc_debug ||
_pgp_debug < 0) && gc->key_pair) rpmgcDump(
"gc->key_pair", gc->key_pair);
725 gc->pub_key = gcry_sexp_find_token(gc->key_pair,
"public-key", 0);
726 if (gc->pub_key ==
NULL)
729 if ((_rpmgc_debug ||
_pgp_debug < 0) && gc->pub_key) rpmgcDump(
"gc->pub_key", gc->pub_key);
731 gc->sec_key = gcry_sexp_find_token(gc->key_pair,
"private-key", 0);
732 if (gc->sec_key ==
NULL)
735 if ((_rpmgc_debug ||
_pgp_debug < 0) && gc->sec_key) rpmgcDump(
"gc->sec_key", gc->sec_key);
739 rc = (gc->err == 0 && gc->pub_key && gc->sec_key);
743 gcry_sexp_release(gc->key_spec);
747 gcry_sexp_release(gc->key_pair);
758 int rpmgcMpiItem(
const char * pre,
pgpDig dig,
int itemno,
766 const char * mpiname =
"";
767 gcry_mpi_t * mpip =
NULL;
775 mpiname =
"ECDSA r"; mpip = &gc->r;
778 mpiname =
"ECDSA s"; mpip = &gc->s;
781 mpiname =
"ECDSA o"; mpip = &gc->o;
784 mpiname =
"ECDSA Q"; mpip = &gc->q;
787 mpiname =
"RSA m**d"; mpip = &gc->c;
790 mpiname =
"DSA r"; mpip = &gc->r;
793 mpiname =
"DSA s"; mpip = &gc->s;
796 mpiname =
"RSA n"; mpip = &gc->n;
799 mpiname =
"RSA e"; mpip = &gc->e;
802 mpiname =
"DSA p"; mpip = &gc->p;
805 mpiname =
"DSA q"; mpip = &gc->q;
808 mpiname =
"DSA g"; mpip = &gc->g;
811 mpiname =
"DSA y"; mpip = &gc->y;
820 nb = (pend >= p ? (pend -
p) : 0);
821 assert(nb >= 2 && nb <= 254);
822 *mpip = gcry_mpi_set_opaque(*mpip, (
void *)p, 8*nb);
825 gc->err = rpmgcErr(gc, mpiname,
826 gcry_mpi_scan(mpip, GCRYMPI_FMT_PGP, p, nb, &nscan) );
832 {
unsigned nbits = gcry_mpi_get_nbits(*mpip);
833 unsigned char * hex =
NULL;
835 gc->err = rpmgcErr(gc,
"MPI print",
836 gcry_mpi_aprint(GCRYMPI_FMT_HEX, &hex, &nhex, *mpip) );
837 fprintf(stderr,
"*** %s\t%5d:%s\n", mpiname, (
int)nbits, hex);
848 void rpmgcClean(
void * impl)
857 gc->digest =
_free(gc->digest);
861 gcry_sexp_release(gc->key_spec);
865 gcry_sexp_release(gc->key_pair);
869 gcry_sexp_release(gc->pub_key);
873 gcry_sexp_release(gc->sec_key);
877 gcry_sexp_release(gc->hash);
881 gcry_sexp_release(gc->sig);
886 gcry_mpi_release(gc->c);
890 gcry_mpi_release(gc->p);
894 gcry_mpi_release(gc->q);
898 gcry_mpi_release(gc->g);
902 gcry_mpi_release(gc->y);
907 gcry_mpi_release(gc->r);
911 gcry_mpi_release(gc->s);
915 gcry_mpi_release(gc->n);
919 gcry_mpi_release(gc->e);
923 gcry_mpi_release(gc->o);
927 gcry_mpi_release(gc->a);
931 gcry_mpi_release(gc->b);
935 gc->oid =
_free(gc->oid);
936 gc->curve =
_free(gc->curve);
944 static int rpmgc_initialized;
947 void * rpmgcFree(
void * impl)
954 if (--rpmgc_initialized == 0 &&
_pgp_debug < 0) {
956 gc->err = rpmgcErr(gc,
"CLEAR_DEBUG_FLAGS",
957 gcry_control(GCRYCTL_CLEAR_DEBUG_FLAGS, 3));
958 gc->err = rpmgcErr(gc,
"SET_VERBOSITY",
959 gcry_control(GCRYCTL_SET_VERBOSITY, 0) );
968 void * rpmgcInit(
void)
974 if (rpmgc_initialized++ == 0 &&
_pgp_debug < 0) {
975 gc->err = rpmgcErr(gc,
"SET_VERBOSITY",
976 gcry_control(GCRYCTL_SET_VERBOSITY, 3) );
977 gc->err = rpmgcErr(gc,
"SET_DEBUG_FLAGS",
978 gcry_control(GCRYCTL_SET_DEBUG_FLAGS, 3) );
991 rpmgcAvailableCipher, rpmgcAvailableDigest, rpmgcAvailablePubkey,
992 rpmgcVerify, rpmgcSign, rpmgcGenerate,
994 rpmgcMpiItem, rpmgcClean,
rpmlog(RPMLOG_ERR,"%s\n", buf)
char * xstrdup(const char *str)
static char *size_t nb
fgets(3) analogue that reads \ continuations.
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
sprintf(t," (%u)",(unsigned) dig->nbytes)
void * xcalloc(size_t nmemb, size_t size)
assert(key->size==sizeof(hdrNum))
struct pgpValTbl_s pgpHashTbl[]
Hash (string, value) pairs.
static char * pgpHexStr(const rpmuint8_t *p, size_t plen)
Return hex formatted representation of bytes.
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.
char * rpmExpand(const char *arg,...)
Return (malloc'ed) concatenated macro expansion(s).
static const char *char c
Return text between pl and matching pr characters.
static int xisdigit(int c)
static unsigned int pgpMpiLen(const rpmuint8_t *p)
Return no.
pgpImplVecs_t rpmgcImplVecs
Implementation specific parameter storage.
#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.
char * buf
Parse (and execute) macro undefinition.
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.
pgpDigParams pgpGetPubkey(pgpDig dig)
Return OpenPGP pubkey parameters.
struct pgpValTbl_s pgpPubkeyTbl[]