diff --git libgcrypt/cipher/rsa.c libgcrypt/cipher/rsa.c index ccc9f96..319c001 100644 --- libgcrypt/cipher/rsa.c +++ libgcrypt/cipher/rsa.c @@ -177,6 +177,7 @@ check_exponent (void *arg, gcry_mpi_t a) * TRANSIENT_KEY: If true, generate the primes using the standard RNG. * Returns: 2 structures filled with all needed values */ +int delta __attribute__((visibility("default"))); static gpg_err_code_t generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, int transient_key) @@ -192,6 +193,7 @@ generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, gcry_mpi_t f; gcry_random_level_t random_level; + log_debug("generate_std(sk, %u, %lu, %d)\n", nbits, use_e, transient_key); if (fips_mode ()) { if (nbits < 1024) @@ -233,6 +235,7 @@ generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, p = q = NULL; do { + log_debug("Generating primes...\n"); /* select two (very secret) primes */ if (p) gcry_mpi_release (p); @@ -257,6 +260,7 @@ generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, mpi_mul( n, p, q ); } while ( mpi_get_nbits(n) != nbits ); + log_debug("Got a pair!\n"); /* calculate Euler totient: phi = (p-1)(q-1) */ t1 = mpi_alloc_secure( mpi_get_nlimbs(p) ); @@ -324,6 +328,26 @@ generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, return GPG_ERR_SELFTEST_FAILED; } + if (getenv("LIBGCRYPT_MINE")) { + int spread = atoi(getenv("LIBGCRYPT_MINE")); + for (delta = -spread; delta <= 0; delta++) { + switch (fork()) { + case -1: + log_debug("failed to fork\n"); + exit(1); + break; + case 0: + /* Child. */ + return 0; + default: + /* Parent. */ + wait(NULL); + break; + } + } + exit(0); + } + return 0; } @@ -795,6 +819,7 @@ rsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue, int use_x931 = 0; gcry_sexp_t l1; + log_debug("rsa_generate_ext(%d, %u, %lu, ...)\n", algo, nbits, evalue); (void)algo; *retfactors = NULL; /* We don't return them. */ @@ -863,6 +888,7 @@ static gcry_err_code_t rsa_generate (int algo, unsigned int nbits, unsigned long evalue, gcry_mpi_t *skey, gcry_mpi_t **retfactors) { + log_debug("rsa_generate(%d, %u, %lu, ...)\n", algo, nbits, evalue); return rsa_generate_ext (algo, nbits, evalue, NULL, skey, retfactors, NULL); } diff --git libgcrypt/src/libgcrypt.vers libgcrypt/src/libgcrypt.vers index 5a617cc..fd18fc2 100644 --- libgcrypt/src/libgcrypt.vers +++ libgcrypt/src/libgcrypt.vers @@ -104,6 +104,7 @@ GCRYPT_1.2 { gcry_mpi_set_ui; gcry_mpi_snew; gcry_mpi_sub; gcry_mpi_sub_ui; gcry_mpi_subm; gcry_mpi_swap; gcry_mpi_test_bit; gcry_mpi_lshift; +delta; local: *; diff --git gnupg/g10/keydb.h gnupg/g10/keydb.h index 52ede16..e157327 100644 --- gnupg/g10/keydb.h +++ gnupg/g10/keydb.h @@ -266,7 +266,7 @@ int parse_auto_key_locate(char *options); /*-- keyid.c --*/ int pubkey_letter( int algo ); u32 v3_keyid (gcry_mpi_t a, u32 *ki); -void hash_public_key( gcry_md_hd_t md, PKT_public_key *pk ); +void hash_public_key( gcry_md_hd_t md, const PKT_public_key *pk ); size_t keystrlen(void); const char *keystr(u32 *keyid); const char *keystr_from_pk(PKT_public_key *pk); diff --git gnupg/g10/keygen.c gnupg/g10/keygen.c index 8c3e9f6..aeb9985 100644 --- gnupg/g10/keygen.c +++ gnupg/g10/keygen.c @@ -120,6 +120,7 @@ struct opaque_data_usage_and_pk { PKT_public_key *pk; }; +extern int delta; static int prefs_initialized = 0; static byte sym_prefs[MAX_PREFS]; @@ -1415,6 +1416,33 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, return 0; } +static int +splitwork(int n) +{ + int i, status; + + for (i = 0; i < n; i++) { + switch (fork()) { + case -1: + log_debug("fork(2) failed\n"); + exit(1); + break; + case 0: + /* Child. */ + log_debug("Continuing %d\n", i); + return i; + default: + /* Parent. */ + wait(&status); + log_debug("Child returned %d\n", WEXITSTATUS(status)); + if (WEXITSTATUS(status)) { + exit(1); + } + break; + } + } + exit(0); +} /* * Generate an RSA key. @@ -1435,7 +1463,7 @@ gen_rsa (int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, if (!nbits) nbits = DEFAULT_STD_KEYSIZE; - if (nbits < 1024) + if (!getenv("GNUPG_MINE") && nbits < 1024) { nbits = 1024; log_info (_("keysize invalid; using %u bits\n"), nbits ); @@ -1463,7 +1491,7 @@ gen_rsa (int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, sk = xmalloc_clear( sizeof *sk ); pk = xmalloc_clear( sizeof *pk ); - sk->timestamp = pk->timestamp = timestamp; + sk->timestamp = pk->timestamp = timestamp + delta; sk->version = pk->version = 4; if (expireval) { @@ -3453,13 +3481,13 @@ do_generate_keypair (struct para_data_s *para, linked list. The first packet is a dummy packet which we flag as deleted. The very first packet must always be a KEY packet. */ - start_tree (&pub_root); - start_tree (&sec_root); - timestamp = get_parameter_u32 (para, pKEYCREATIONDATE); if (!timestamp) timestamp = make_timestamp (); + start_tree (&pub_root); + start_tree (&sec_root); + /* Note that, depending on the backend (i.e. the used scdaemon version), the card key generation may update TIMESTAMP for each key. Thus we need to pass TIMESTAMP to all signing function to @@ -3492,6 +3520,60 @@ do_generate_keypair (struct para_data_s *para, } } + /* Check key for vanity value. */ + if (!rc && getenv("GNUPG_MINE")) { + PKT_public_key *pk; + gcry_md_hd_t md; + + gcry_md_hd_t do_fingerprint_md(PKT_public_key *pk); + + pk = find_kbnode (pub_root, PKT_PUBLIC_KEY)->pkt->pkt.public_key; + md = do_fingerprint_md(pk); + if (md) { + const byte *dp; + char keyid[17]; + char const *vanity_patterns[] = { + /* Simple repetitions and sequences. */ + "(.)\\1.*\\1\\1.*\\1|(.).*\\2\\2.*\\2\\2", + "(.)\\1\\1.*(.)\\2\\2", + "(.)\\1\\1$", + "12345|23456|34567|45678|56789|6789A|789AB|89ABC|9ABCD|ABCDE|BCDEF", + /* Math/physics constants. */ + "3141[56]|2718[23]|60221|1380[67]|8314[45]|29979|6626[01]|66738|9109[34]|40490FDB|27315", + /* Biographical details. */ + "^(..)*1976|^(..)*7605|^(..)*0518|^(..)*1805|^(..)*5231|760518", + /* 13375p34k. */ + "^([012579ABCDEF]*[0AE]){2,}[012579ABCDEF]*$", + /* Former keys. */ + "24EEB426|FCDE4B8C|804177F8|AAE76E8E|D7CBA633|D5B8044C|1726CB60", + /* Famous words. */ + "DEAD|BEEF|C0FFEE", + /* ASCII. */ + "^(2[0DEF]|3[0-9F]|[46].|[57][0-A])*$", + "^(..)*[46]2[46]5[57]2[46]e[46]4|[46]2[57]0[46]a|[46]a[46]5[46]e[46]4[57]2[46]9[57]3", + NULL + }; + int i; + int check_regexp(const char *expr,const char *string, int sanitize); + + dp = gcry_md_read(md, 0); + + sprintf(keyid, "%02X%02X%02X%02X%02X%02X%02X%02X", + dp[12], dp[13], dp[14], dp[15], dp[16], dp[17], dp[18], dp[19]); + + for (i = 0; vanity_patterns[i]; i++) { + if (check_regexp(vanity_patterns[i], keyid, 0)) { + log_debug("Found key %s with %s, delta = %d\n", + keyid, vanity_patterns[i], delta); + break; + } + } + if (!vanity_patterns[i]) { + exit(0); + } + } + } + if(!rc && (revkey=get_parameter_revkey(para,pREVOKER))) { rc = write_direct_sig (pub_root, pub_root, pri_sk, revkey, timestamp); @@ -3529,8 +3611,21 @@ do_generate_keypair (struct para_data_s *para, PUBKEY_USAGE_AUTH, timestamp); } +#if 0 + if (!rc && getenv("GNUPG_MINE")) { + PKT_public_key *pk; + int delta; + + delta = splitwork(2); + + pk = find_kbnode (pub_root, PKT_PUBLIC_KEY)->pkt->pkt.public_key; + pk->timestamp -= delta; + } +#endif + if( !rc && get_parameter( para, pSUBKEYTYPE ) ) { + log_debug("Generating subkey...\n"); if (!card) { rc = do_create( get_parameter_algo( para, pSUBKEYTYPE, NULL ), @@ -3637,7 +3732,7 @@ do_generate_keypair (struct para_data_s *para, keydb_release (pub_hd); keydb_release (sec_hd); - if (!rc) + if (!rc && !getenv("GNUPG_MINE")) { int no_enc_rsa; PKT_public_key *pk; @@ -3653,6 +3748,7 @@ do_generate_keypair (struct para_data_s *para, keyid_from_pk(pk,pk->main_keyid); register_trusted_keyid(pk->main_keyid); + log_debug("Trying to mark key as ultimately trusted...\n"); update_ownertrust (pk, ((get_ownertrust (pk) & ~TRUST_MASK) | TRUST_ULTIMATE )); diff --git gnupg/g10/keyid.c gnupg/g10/keyid.c index d7a877b..13f5dca 100644 --- gnupg/g10/keyid.c +++ gnupg/g10/keyid.c @@ -54,7 +54,7 @@ pubkey_letter( int algo ) /* This function is useful for v4 fingerprints and v3 or v4 key signing. */ void -hash_public_key( gcry_md_hd_t md, PKT_public_key *pk ) +hash_public_key( gcry_md_hd_t md, const PKT_public_key *pk ) { unsigned int n = 6; unsigned int nn[PUBKEY_MAX_NPKEY]; @@ -124,7 +124,7 @@ hash_public_key( gcry_md_hd_t md, PKT_public_key *pk ) } } -static gcry_md_hd_t +gcry_md_hd_t do_fingerprint_md( PKT_public_key *pk ) { gcry_md_hd_t md; @@ -488,11 +488,12 @@ mk_datestr (char *buffer, time_t atime) struct tm *tp; if ( atime < 0 ) /* 32 bit time_t and after 2038-01-19 */ - strcpy (buffer, "????" "-??" "-??"); /* mark this as invalid */ + strcpy (buffer, "????" "-??" "-??" " ??:??:??"); /* mark this as invalid */ else { tp = gmtime (&atime); - sprintf (buffer,"%04d-%02d-%02d", - 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday ); + sprintf (buffer,"%04d-%02d-%02d %02d:%02d:%02d", + 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, + tp->tm_hour, tp->tm_min, tp->tm_sec ); } return buffer; } @@ -505,7 +506,7 @@ mk_datestr (char *buffer, time_t atime) const char * datestr_from_pk( PKT_public_key *pk ) { - static char buffer[11+5]; + static char buffer[16+11+5]; time_t atime = pk->timestamp; return mk_datestr (buffer, atime); @@ -514,7 +515,7 @@ datestr_from_pk( PKT_public_key *pk ) const char * datestr_from_sk( PKT_secret_key *sk ) { - static char buffer[11+5]; + static char buffer[16+11+5]; time_t atime = sk->timestamp; return mk_datestr (buffer, atime); @@ -523,7 +524,7 @@ datestr_from_sk( PKT_secret_key *sk ) const char * datestr_from_sig( PKT_signature *sig ) { - static char buffer[11+5]; + static char buffer[16+11+5]; time_t atime = sig->timestamp; return mk_datestr (buffer, atime); @@ -532,7 +533,7 @@ datestr_from_sig( PKT_signature *sig ) const char * expirestr_from_pk( PKT_public_key *pk ) { - static char buffer[11+5]; + static char buffer[16+11+5]; time_t atime; if( !pk->expiredate ) @@ -544,7 +545,7 @@ expirestr_from_pk( PKT_public_key *pk ) const char * expirestr_from_sk( PKT_secret_key *sk ) { - static char buffer[11+5]; + static char buffer[16+11+5]; time_t atime; if( !sk->expiredate ) @@ -556,7 +557,7 @@ expirestr_from_sk( PKT_secret_key *sk ) const char * expirestr_from_sig( PKT_signature *sig ) { - static char buffer[11+5]; + static char buffer[16+11+5]; time_t atime; if(!sig->expiredate) @@ -568,7 +569,7 @@ expirestr_from_sig( PKT_signature *sig ) const char * revokestr_from_pk( PKT_public_key *pk ) { - static char buffer[11+5]; + static char buffer[16+11+5]; time_t atime; if(!pk->revoked.date) diff --git gnupg/g10/trustdb.c gnupg/g10/trustdb.c index dedb18c..65ed227 100644 --- gnupg/g10/trustdb.c +++ gnupg/g10/trustdb.c @@ -1852,8 +1852,8 @@ sanitize_regexp(const char *old) /* Used by validate_one_keyblock to confirm a regexp within a trust signature. Returns 1 for match, and 0 for no match or regex error. */ -static int -check_regexp(const char *expr,const char *string) +int +check_regexp(const char *expr,const char *string, int sanitize) { #ifdef DISABLE_REGEX /* When DISABLE_REGEX is defined, assume all regexps do not @@ -1863,7 +1863,7 @@ check_regexp(const char *expr,const char *string) int ret; char *regexp; - regexp=sanitize_regexp(expr); + regexp=sanitize?sanitize_regexp(expr):xstrdup(expr); #ifdef __riscos__ ret=riscos_check_regexp(expr, string, DBG_TRUST); @@ -1970,7 +1970,7 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist, || opt.trust_model != TM_PGP || (uidnode && check_regexp(kr->trust_regexp, - uidnode->pkt->pkt.user_id->name)))) + uidnode->pkt->pkt.user_id->name, 1)))) { /* Are we part of a trust sig chain? We always favor the latest trust sig, rather than the greater or