diff options
Diffstat (limited to 'programs/rsasigkey')
-rw-r--r-- | programs/rsasigkey/.cvsignore | 1 | ||||
-rw-r--r-- | programs/rsasigkey/Makefile | 39 | ||||
-rw-r--r-- | programs/rsasigkey/rsasigkey.8 | 259 | ||||
-rw-r--r-- | programs/rsasigkey/rsasigkey.c | 573 |
4 files changed, 0 insertions, 872 deletions
diff --git a/programs/rsasigkey/.cvsignore b/programs/rsasigkey/.cvsignore deleted file mode 100644 index f9e610b4d..000000000 --- a/programs/rsasigkey/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -rsasigkey diff --git a/programs/rsasigkey/Makefile b/programs/rsasigkey/Makefile deleted file mode 100644 index c2b82e5c8..000000000 --- a/programs/rsasigkey/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# Makefile for miscelaneous programs -# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org> -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 2 of the License, or (at your -# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:30 as Exp $ - -FREESWANSRCDIR=../.. -include ${FREESWANSRCDIR}/Makefile.inc - -PROGRAM=rsasigkey -LIBS=${FREESWANLIB} -lgmp - -include ../Makefile.program - -# -# $Log: Makefile,v $ -# Revision 1.1 2004/03/15 20:35:30 as -# added files from freeswan-2.04-x509-1.5.3 -# -# Revision 1.2 2002/06/02 21:51:41 mcr -# changed TOPDIR->FREESWANSRCDIR in all Makefiles. -# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the -# kernel sense.) -# -# Revision 1.1 2002/04/24 07:55:32 mcr -# #include patches and Makefiles for post-reorg compilation. -# -# -# - diff --git a/programs/rsasigkey/rsasigkey.8 b/programs/rsasigkey/rsasigkey.8 deleted file mode 100644 index c64dd46bd..000000000 --- a/programs/rsasigkey/rsasigkey.8 +++ /dev/null @@ -1,259 +0,0 @@ -.TH IPSEC_RSASIGKEY 8 "22 July 2001" -.\" RCSID $Id: rsasigkey.8,v 1.1 2004/03/15 20:35:30 as Exp $ -.SH NAME -ipsec rsasigkey \- generate RSA signature key -.SH SYNOPSIS -.B ipsec -.B rsasigkey -[ -.B \-\-verbose -] [ -.B \-\-random -filename -] -.B \e -.br -\ \ \ [ -.B \-\-rounds -nr -] [ -.B \-\-hostname -host ] [ -.B \-\-noopt -] nbits -.br -.B ipsec -.B rsasigkey -[ -.B \-\-verbose -] [ -.B \-\-hostname -host ] -.B \e -.br -\ \ \ -[ -.B \-\-noopt -] -.B \-\-oldkey -file -.SH DESCRIPTION -.I Rsasigkey -generates an RSA public/private key pair, -suitable for digital signatures, -of (exactly) -.I nbits -bits (that is, two primes each of exactly -.IR nbits /2 -bits, -and related numbers) -and emits it on standard output as ASCII (mostly hex) data. -.I nbits -must be a multiple of 16. -.PP -The public exponent is forced to the value -.BR 3 , -which has important speed advantages for signature checking. -Beware that the resulting keys have known weaknesses as encryption keys -\fIand should not be used for that purpose\fR. -.PP -The -.B \-\-verbose -option makes -.I rsasigkey -give a running commentary on standard error. -By default, it works in silence until it is ready to generate output. -.PP -The -.B \-\-random -option specifies a source for random bits. -The default is -.I /dev/random -(see -.IR random (4)). -Normally, -.I rsasigkey -reads exactly -.I nbits -random bits from the source; -in extremely-rare circumstances it may need more. -.PP -The -.B \-\-rounds -option specifies the number of rounds to be done by the -.I mpz_probab_prime_p -probabilistic primality checker. -The default, 30, is fairly rigorous and should not normally -have to be overridden. -.PP -The -.B \-\-hostname -option specifies what host name to use in -the first line of the output (see below); -the default is what -.IR gethostname (2) -returns. -.PP -The -.B \-\-noopt -option suppresses an optimization of the private key -(to be precise, setting of the decryption exponent to -.B lcm(p\-1,q\-1) -rather than -.BR (p\-1)*(q\-1) ) -which speeds up operations on it slightly -but can cause it to flunk a validity check in old RSA implementations -(notably, obsolete versions of -.IR ipsec_pluto (8)). -.PP -The -.B \-\-oldkey -option specifies that rather than generate a new key, -.I rsasigkey -should read an old key from the -.I file -(the name -.B \- -means ``standard input'') -and use that to generate its output. -Input lines which do not look like -.I rsasigkey -output are silently ignored. -This permits updating old keys to the current format. -.PP -The output format looks like this (with long numbers trimmed down -for clarity): -.PP -.ne 15 -.nf - # RSA 2048 bits xy.example.com Sat Apr 15 13:53:22 2000 - # for signatures only, UNSAFE FOR ENCRYPTION - #pubkey=0sAQOF8tZ2NZt...Y1P+buFuFn/ - Modulus: 0xcc2a86fcf440...cf1011abb82d1 - PublicExponent: 0x03 - # everything after this point is secret - PrivateExponent: 0x881c59fdf8...ab05c8c77d23 - Prime1: 0xf49fd1f779...46504c7bf3 - Prime2: 0xd5a9108453...321d43cb2b - Exponent1: 0xa31536a4fb...536d98adda7f7 - Exponent2: 0x8e70b5ad8d...9142168d7dcc7 - Coefficient: 0xafb761d001...0c13e98d98 -.fi -.PP -The first (comment) line, -indicating the nature and date of the key, -and giving a host name, -is used by -.IR ipsec_showhostkey (8) -when generating some forms of key output. -.PP -The commented-out -.B pubkey= -line contains the public key\(emthe public exponent and the modulus\(emcombined -in approximately RFC 2537 format -(the one deviation is that the combined value is given with a -.B 0s -prefix, rather than in unadorned base-64), -suitable for use in the -.I ipsec.conf -file. -.PP -The -.BR Modulus , -.BR PublicExponent , -and -.B PrivateExponent -lines give the basic signing and verification data. -.PP -The -.B Prime1 -and -.B Prime2 -lines give the primes themselves (aka -.I p -and -.IR q ), -largest first. -The -.B Exponent1 -and -.B Exponent2 -lines give -the private exponent mod -.IR p\-1 -and -.IR q\-1 -respectively. -The -.B Coefficient -line gives the Chinese Remainder Theorem coefficient, -which is the inverse of -.IR q , -mod -.IR p . -These additional numbers (which must all be kept as secret as the -private exponent) are precomputed aids to rapid signature generation. -.PP -No attempt is made to break long lines. -.PP -The US patent on the RSA algorithm expired 20 Sept 2000. -.SH EXAMPLES -.TP -.B "ipsec rsasigkey \-\-verbose 2192 >mykey" -generates a 2192-bit signature key and puts it in the file -.IR mykey , -with running commentary on standard error. -The file contents can be inserted verbatim into a suitable entry in the -.I ipsec.secrets -file (see -.IR ipsec.secrets (5)), -and the public key can then be extracted and edited into the -.I ipsec.conf -file (see -.IR ipsec.conf (5)). -.TP -.B "ipsec rsasigkey \-\-verbose \-\-oldkey oldie >latest" -takes the old signature key from file -.I oldie -and puts a version in the current format into the file -.IR latest , -with running commentary on standard error. -.SH FILES -/dev/random -.SH SEE ALSO -random(4), ipsec_showhostkey(8) -.br -\fIApplied Cryptography\fR, 2nd. ed., by Bruce Schneier, Wiley 1996. -.br -RFCs 2537, 2313. -.br -\fIGNU MP, the GNU multiple precision arithmetic library, edition 2.0.2\fR, -by Torbj Granlund. -.SH HISTORY -Written for the Linux FreeS/WAN project -<http://www.freeswan.org> -by Henry Spencer. -.SH BUGS -There is an internal limit on -.IR nbits , -currently 20000. -.PP -.IR Rsasigkey 's -run time is difficult to predict, -since -.I /dev/random -output can be arbitrarily delayed if -the system's entropy pool is low on randomness, -and the time taken by the search for primes is also somewhat unpredictable. -A reasonably typical time for a 1024-bit key on a quiet 200MHz Pentium MMX -with plenty of randomness available is 20 seconds, -almost all of it in the prime searches. -Generating a 2192-bit key on the same system usually takes several minutes. -A 4096-bit key took an hour and a half of CPU time. -.PP -The -.B \-\-oldkey -option does not check its input format as rigorously as it might. -Corrupted -.I rsasigkey -output may confuse it. diff --git a/programs/rsasigkey/rsasigkey.c b/programs/rsasigkey/rsasigkey.c deleted file mode 100644 index b55dbb889..000000000 --- a/programs/rsasigkey/rsasigkey.c +++ /dev/null @@ -1,573 +0,0 @@ -/* - * RSA signature key generation - * Copyright (C) 1999, 2000, 2001 Henry Spencer. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * RCSID $Id: rsasigkey.c,v 1.2 2005/08/11 10:35:58 as Exp $ - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdlib.h> -#include <unistd.h> -#include <stdio.h> -#include <time.h> -#include <limits.h> -#include <errno.h> -#include <string.h> -#include <assert.h> -#include <getopt.h> -#include <freeswan.h> -#include "gmp.h" - -#ifndef DEVICE -#define DEVICE "/dev/random" -#endif -#ifndef MAXBITS -#define MAXBITS 20000 -#endif - -/* the code in getoldkey() knows about this */ -#define E 3 /* standard public exponent */ - -char usage[] = "rsasigkey [--verbose] [--random device] nbits"; -char usage2[] = "rsasigkey [--verbose] --oldkey filename"; -struct option opts[] = { - {"verbose", 0, NULL, 'v',}, - {"random", 1, NULL, 'r',}, - {"rounds", 1, NULL, 'p',}, - {"oldkey", 1, NULL, 'o',}, - {"hostname", 1, NULL, 'H',}, - {"noopt", 0, NULL, 'n',}, - {"help", 0, NULL, 'h',}, - {"version", 0, NULL, 'V',}, - {0, 0, NULL, 0,} -}; -int verbose = 0; /* narrate the action? */ -char *device = DEVICE; /* where to get randomness */ -int nrounds = 30; /* rounds of prime checking; 25 is good */ -mpz_t prime1; /* old key's prime1 */ -mpz_t prime2; /* old key's prime2 */ -char outputhostname[1024]; /* hostname for output */ -int do_lcm = 1; /* use lcm(p-1, q-1), not (p-1)*(q-1) */ - -char me[] = "ipsec rsasigkey"; /* for messages */ - -/* forwards */ -int getoldkey(char *filename); -void rsasigkey(int nbits, int useoldkey); -void initprime(mpz_t var, int nbits, int eval); -void initrandom(mpz_t var, int nbits); -void getrandom(size_t nbytes, char *buf); -char *bundle(int e, mpz_t n, size_t *sizep); -char *conv(char *bits, size_t nbytes, int format); -char *hexout(mpz_t var); -void report(char *msg); - -/* - - main - mostly argument parsing - */ -int main(int argc, char *argv[]) -{ - int opt; - extern int optind; - extern char *optarg; - int errflg = 0; - int i; - int nbits; - char *oldkeyfile = NULL; - - while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF) - switch (opt) { - case 'v': /* verbose description */ - verbose = 1; - break; - case 'r': /* nonstandard /dev/random */ - device = optarg; - break; - case 'p': /* number of prime-check rounds */ - nrounds = atoi(optarg); - if (nrounds <= 0) { - fprintf(stderr, "%s: rounds must be > 0\n", me); - exit(2); - } - break; - case 'o': /* reformat old key */ - oldkeyfile = optarg; - break; - case 'H': /* set hostname for output */ - strcpy(outputhostname, optarg); - break; - case 'n': /* don't optimize the private key */ - do_lcm = 0; - break; - case 'h': /* help */ - printf("Usage:\t%s\n", usage); - printf("\tor\n"); - printf("\t%s\n", usage2); - exit(0); - break; - case 'V': /* version */ - printf("%s %s\n", me, ipsec_version_code()); - exit(0); - break; - case '?': - default: - errflg = 1; - break; - } - if (errflg || optind != ((oldkeyfile != NULL) ? argc : argc-1)) { - printf("Usage:\t%s\n", usage); - printf("\tor\n"); - printf("\t%s\n", usage2); - exit(2); - } - - if (outputhostname[0] == '\0') { - i = gethostname(outputhostname, sizeof(outputhostname)); - if (i < 0) { - fprintf(stderr, "%s: gethostname failed (%s)\n", - me, - strerror(errno)); - exit(1); - } - } - - if (oldkeyfile == NULL) { - assert(argv[optind] != NULL); - nbits = atoi(argv[optind]); - } else - nbits = getoldkey(oldkeyfile); - - if (nbits <= 0) { - fprintf(stderr, "%s: invalid bit count (%d)\n", me, nbits); - exit(1); - } else if (nbits > MAXBITS) { - fprintf(stderr, "%s: overlarge bit count (max %d)\n", me, - MAXBITS); - exit(1); - } else if (nbits % (CHAR_BIT*2) != 0) { /* *2 for nbits/2-bit primes */ - fprintf(stderr, "%s: bit count (%d) not multiple of %d\n", me, - nbits, (int)CHAR_BIT*2); - exit(1); - } - - rsasigkey(nbits, (oldkeyfile == NULL) ? 0 : 1); - exit(0); -} - -/* - - getoldkey - fetch an old key's primes - */ -int /* nbits */ -getoldkey(filename) -char *filename; -{ - FILE *f; - char line[MAXBITS/2]; - char *p; - char *value; - static char pube[] = "PublicExponent:"; - static char pubevalue[] = "0x03"; - static char pr1[] = "Prime1:"; - static char pr2[] = "Prime2:"; -# define STREQ(a, b) (strcmp(a, b) == 0) - int sawpube = 0; - int sawpr1 = 0; - int sawpr2 = 0; - int nbits; - - nbits = 0; - - if (STREQ(filename, "-")) - f = stdin; - else - f = fopen(filename, "r"); - if (f == NULL) { - fprintf(stderr, "%s: unable to open file `%s' (%s)\n", me, - filename, strerror(errno)); - exit(1); - } - if (verbose) - fprintf(stderr, "getting old key from %s...\n", filename); - - while (fgets(line, sizeof(line), f) != NULL) { - p = line + strlen(line) - 1; - if (*p != '\n') { - fprintf(stderr, "%s: over-long line in file `%s'\n", - me, filename); - exit(1); - } - *p = '\0'; - - p = line + strspn(line, " \t"); /* p -> first word */ - value = strpbrk(p, " \t"); /* value -> after it */ - if (value != NULL) { - *value++ = '\0'; - value += strspn(value, " \t"); - /* value -> second word if any */ - } - - if (value == NULL || *value == '\0') { - /* wrong format */ - } else if (STREQ(p, pube)) { - sawpube = 1; - if (!STREQ(value, pubevalue)) { - fprintf(stderr, "%s: wrong public exponent (`%s') in old key\n", - me, value); - exit(1); - } - } else if (STREQ(p, pr1)) { - if (sawpr1) { - fprintf(stderr, "%s: duplicate `%s' lines in `%s'\n", - me, pr1, filename); - exit(1); - } - sawpr1 = 1; - nbits = (strlen(value) - 2) * 4 * 2; - if (mpz_init_set_str(prime1, value, 0) < 0) { - fprintf(stderr, "%s: conversion error in reading old prime1\n", - me); - exit(1); - } - } else if (STREQ(p, pr2)) { - if (sawpr2) { - fprintf(stderr, "%s: duplicate `%s' lines in `%s'\n", - me, pr2, filename); - exit(1); - } - sawpr2 = 1; - if (mpz_init_set_str(prime2, value, 0) < 0) { - fprintf(stderr, "%s: conversion error in reading old prime2\n", - me); - exit(1); - } - } - } - - if (f != stdin) - fclose(f); - - if (!sawpube || !sawpr1 || !sawpr2) { - fprintf(stderr, "%s: old key missing or incomplete\n", me); - exit(1); - } - - assert(sawpr1); /* and thus nbits is known */ - return(nbits); -} - -/* - - rsasigkey - generate an RSA signature key - * e is fixed at 3, without discussion. That would not be wise if these - * keys were to be used for encryption, but for signatures there are some - * real speed advantages. - */ -void -rsasigkey(nbits, useoldkey) -int nbits; -int useoldkey; /* take primes from old key? */ -{ - mpz_t p; - mpz_t q; - mpz_t n; - mpz_t e; - mpz_t d; - mpz_t q1; /* temporary */ - mpz_t m; /* internal modulus, (p-1)*(q-1) */ - mpz_t t; /* temporary */ - mpz_t exp1; - mpz_t exp2; - mpz_t coeff; - char *bundp; - size_t bs; - int success; - time_t now = time((time_t *)NULL); - - /* the easy stuff */ - if (useoldkey) { - mpz_init_set(p, prime1); - mpz_init_set(q, prime2); - } else { - initprime(p, nbits/2, E); - initprime(q, nbits/2, E); - } - mpz_init(t); - if (mpz_cmp(p, q) < 0) { - report("swapping primes so p is the larger..."); - mpz_set(t, p); - mpz_set(p, q); - mpz_set(q, t); - } - report("computing modulus..."); - mpz_init(n); - mpz_mul(n, p, q); /* n = p*q */ - mpz_init_set_ui(e, E); - - /* internal modulus */ - report("computing lcm(p-1, q-1)..."); - mpz_init_set(m, p); - mpz_sub_ui(m, m, 1); - mpz_init_set(q1, q); - mpz_sub_ui(q1, q1, 1); - mpz_gcd(t, m, q1); /* t = gcd(p-1, q-1) */ - mpz_mul(m, m, q1); /* m = (p-1)*(q-1) */ - if (do_lcm) - mpz_divexact(m, m, t); /* m = lcm(p-1, q-1) */ - mpz_gcd(t, m, e); - assert(mpz_cmp_ui(t, 1) == 0); /* m and e relatively prime */ - - /* decryption key */ - report("computing d..."); - mpz_init(d); - success = mpz_invert(d, e, m); - assert(success); /* e has an inverse mod m */ - if (mpz_cmp_ui(d, 0) < 0) - mpz_add(d, d, m); - assert(mpz_cmp(d, m) < 0); - - /* the speedup hacks */ - report("computing exp1, exp1, coeff..."); - mpz_init(exp1); - mpz_sub_ui(t, p, 1); - mpz_mod(exp1, d, t); /* exp1 = d mod p-1 */ - mpz_init(exp2); - mpz_sub_ui(t, q, 1); - mpz_mod(exp2, d, t); /* exp2 = d mod q-1 */ - mpz_init(coeff); - mpz_invert(coeff, q, p); /* coeff = q^-1 mod p */ - if (mpz_cmp_ui(coeff, 0) < 0) - mpz_add(coeff, coeff, p); - assert(mpz_cmp(coeff, p) < 0); - - /* and the output */ - /* note, getoldkey() knows about some of this */ - report("output...\n"); /* deliberate extra newline */ - printf("\t# RSA %d bits %s %s", nbits, outputhostname, ctime(&now)); - /* ctime provides \n */ - printf("\t# for signatures only, UNSAFE FOR ENCRYPTION\n"); - bundp = bundle(E, n, &bs); - printf("\t#pubkey=%s\n", conv(bundp, bs, 's')); /* RFC2537ish format */ - printf("\tModulus: %s\n", hexout(n)); - printf("\tPublicExponent: %s\n", hexout(e)); - printf("\t# everything after this point is secret\n"); - printf("\tPrivateExponent: %s\n", hexout(d)); - printf("\tPrime1: %s\n", hexout(p)); - printf("\tPrime2: %s\n", hexout(q)); - printf("\tExponent1: %s\n", hexout(exp1)); - printf("\tExponent2: %s\n", hexout(exp2)); - printf("\tCoefficient: %s\n", hexout(coeff)); -} - -/* - - initprime - initialize an mpz_t to a random prime of specified size - * Efficiency tweak: we reject candidates that are 1 higher than a multiple - * of e, since they will make the internal modulus not relatively prime to e. - */ -void -initprime(var, nbits, eval) -mpz_t var; -int nbits; /* known to be a multiple of CHAR_BIT */ -int eval; /* value of e; 0 means don't bother w. tweak */ -{ - unsigned long tries; - size_t len; -# define OKAY(p) (eval == 0 || mpz_fdiv_ui(p, eval) != 1) - - initrandom(var, nbits); - assert(mpz_fdiv_ui(var, 2) == 1); /* odd number */ - - report("looking for a prime starting there (can take a while)..."); - tries = 1; - while (!( OKAY(var) && mpz_probab_prime_p(var, nrounds) )) { - mpz_add_ui(var, var, 2); - tries++; - } - - len = mpz_sizeinbase(var, 2); - assert(len == (size_t)nbits || len == (size_t)(nbits+1)); - if (len == (size_t)(nbits+1)) { - report("carry out occurred (!), retrying..."); - mpz_clear(var); - initprime(var, nbits, eval); - return; - } - if (verbose) - fprintf(stderr, "found it after %lu tries.\n", tries); -} - -/* - - initrandom - initialize an mpz_t to a random number, specified bit count - * Converting via hex is a bit weird, but it's the best route GMP gives us. - * Note that highmost and lowmost bits are forced on -- highmost to give a - * number of exactly the specified length, lowmost so it is an odd number. - */ -void -initrandom(var, nbits) -mpz_t var; -int nbits; /* known to be a multiple of CHAR_BIT */ -{ - size_t nbytes = (size_t)(nbits / CHAR_BIT); - static char bitbuf[MAXBITS/CHAR_BIT]; - static char hexbuf[2 + MAXBITS/4 + 1]; - size_t hsize = sizeof(hexbuf); - - assert(nbytes <= sizeof(bitbuf)); - getrandom(nbytes, bitbuf); - bitbuf[0] |= 01 << (CHAR_BIT-1); /* force high bit on */ - bitbuf[nbytes-1] |= 01; /* force low bit on */ - if (datatot(bitbuf, nbytes, 'x', hexbuf, hsize) > hsize) { - fprintf(stderr, "%s: can't-happen buffer overflow\n", me); - exit(1); - } - if (mpz_init_set_str(var, hexbuf, 0) < 0) { - fprintf(stderr, "%s: can't-happen hex conversion error\n", me); - exit(1); - } -} - -/* - - getrandom - get some random bytes from /dev/random (or wherever) - */ -void -getrandom(nbytes, buf) -size_t nbytes; -char *buf; /* known to be big enough */ -{ - size_t ndone; - int dev; - size_t got; - - dev = open(device, 0); - if (dev < 0) { - fprintf(stderr, "%s: could not open %s (%s)\n", me, - device, strerror(errno)); - exit(1); - } - - ndone = 0; - if (verbose) - fprintf(stderr, "getting %d random bytes from %s...\n", (int) nbytes, - device); - while (ndone < nbytes) { - got = read(dev, buf + ndone, nbytes - ndone); - if (got < 0) { - fprintf(stderr, "%s: read error on %s (%s)\n", me, - device, strerror(errno)); - exit(1); - } - if (got == 0) { - fprintf(stderr, "%s: eof on %s!?!\n", me, device); - exit(1); - } - ndone += got; - } - - close(dev); -} - -/* - - hexout - prepare hex output, guaranteeing even number of digits - * (The current FreeS/WAN conversion routines want an even digit count, - * but mpz_get_str doesn't promise one.) - */ -char * /* pointer to static buffer (ick) */ -hexout(var) -mpz_t var; -{ - static char hexbuf[3 + MAXBITS/4 + 1]; - char *hexp; - - mpz_get_str(hexbuf+3, 16, var); - if (strlen(hexbuf+3)%2 == 0) /* even number of hex digits */ - hexp = hexbuf+1; - else { /* odd, must pad */ - hexp = hexbuf; - hexp[2] = '0'; - } - hexp[0] = '0'; - hexp[1] = 'x'; - - return hexp; -} - -/* - - bundle - bundle e and n into an RFC2537-format lump - * Note, calls hexout. - */ -char * /* pointer to static buffer (ick) */ -bundle(e, n, sizep) -int e; -mpz_t n; -size_t *sizep; -{ - char *hexp = hexout(n); - static char bundbuf[2 + MAXBITS/8]; - const char *er; - size_t size; - - assert(e <= 255); - bundbuf[0] = 1; - bundbuf[1] = e; - er = ttodata(hexp, 0, 0, bundbuf+2, sizeof(bundbuf)-2, &size); - if (er != NULL) { - fprintf(stderr, "%s: can't-happen bundle convert error `%s'\n", - me, er); - exit(1); - } - if (size > sizeof(bundbuf)-2) { - fprintf(stderr, "%s: can't-happen bundle overflow (need %d)\n", - me, (int) size); - exit(1); - } - if (sizep != NULL) - *sizep = size + 2; - return bundbuf; -} - -/* - - conv - convert bits to output in specified format - */ -char * /* pointer to static buffer (ick) */ -conv(bits, nbytes, format) -char *bits; -size_t nbytes; -int format; /* datatot() code */ -{ - static char convbuf[MAXBITS/4 + 50]; /* enough for hex */ - size_t n; - - n = datatot(bits, nbytes, format, convbuf, sizeof(convbuf)); - if (n == 0) { - fprintf(stderr, "%s: can't-happen convert error\n", me); - exit(1); - } - if (n > sizeof(convbuf)) { - fprintf(stderr, "%s: can't-happen convert overflow (need %d)\n", - me, (int) n); - exit(1); - } - return convbuf; -} - -/* - - report - report progress, if indicated - */ -void -report(msg) -char *msg; -{ - if (!verbose) - return; - fprintf(stderr, "%s\n", msg); -} |