📄 ntp-keygen.c
字号:
/* * Program to generate cryptographic keys for NTP clients and servers * * This program generates files "ntpkey_<type>_<hostname>.<filestamp>", * where <type> is the file type, <hostname> is the generating host and * <filestamp> is the NTP seconds in decimal format. The NTP programs * expect generic names such as "ntpkey_<type>_whimsy.udel.edu" with the * association maintained by soft links. * * Files are prefixed with a header giving the name and date of creation * followed by a type-specific descriptive label and PEM-encoded data * string compatible with programs of the OpenSSL library. * * Note that private keys can be password encrypted as per OpenSSL * conventions. * * The file types include * * ntpkey_MD5key_<hostname>.<filestamp> * MD5 (128-bit) keys used to compute message digests in symmetric * key cryptography * * ntpkey_RSAkey_<hostname>.<filestamp> * ntpkey_host_<hostname> (RSA) link * RSA private/public host key pair used for public key signatures * and data encryption * * ntpkey_DSAkey_<hostname>.<filestamp> * ntpkey_sign_<hostname> (RSA or DSA) link * DSA private/public sign key pair used for public key signatures, * but not data encryption * * ntpkey_IFFpar_<hostname>.<filestamp> * ntpkey_iff_<hostname> (IFF server/client) link * ntpkey_iffkey_<hostname> (IFF client) link * Schnorr (IFF) server/client identity parameters * * ntpkey_IFFkey_<hostname>.<filestamp> * Schnorr (IFF) client identity parameters * * ntpkey_GQpar_<hostname>.<filestamp>, * ntpkey_gq_<hostname> (GQ) link * Guillou-Quisquater (GQ) identity parameters * * ntpkey_MVpar_<hostname>.<filestamp>, * Mu-Varadharajan (MV) server identity parameters * * ntpkey_MVkeyX_<hostname>.<filestamp>, * ntpkey_mv_<hostname> (MV server) link * ntpkey_mvkey_<hostname> (MV client) link * Mu-Varadharajan (MV) client identity parameters * * ntpkey_XXXcert_<hostname>.<filestamp> * ntpkey_cert_<hostname> (RSA or DSA) link * X509v3 certificate using RSA or DSA public keys and signatures. * XXX is a code identifying the message digest and signature * encryption algorithm * * Available digest/signature schemes * * RSA: RSA-MD2, RSA-MD5, RSA-SHA, RSA-SHA1, RSA-MDC2, EVP-RIPEMD160 * DSA: DSA-SHA, DSA-SHA1 * * Note: Once in a while because of some statistical fluke this program * fails to generate and verify some cryptographic data, as indicated by * exit status -1. In this case simply run the program again. If the * program does complete with return code 0, the data are correct as * verified. * * These cryptographic routines are characterized by the prime modulus * size in bits. The default value of 512 bits is a compromise between * cryptographic strength and computing time and is ordinarily * considered adequate for this application. The routines have been * tested with sizes of 256, 512, 1024 and 2048 bits. Not all message * digest and signature encryption schemes work with sizes less than 512 * bits. The computing time for sizes greater than 2048 bits is * prohibitive on all but the fastest processors. An UltraSPARC Blade * 1000 took something over nine minutes to generate and verify the * values with size 2048. An old SPARC IPC would take a week. * * The OpenSSL library used by this program expects a random seed file. * As described in the OpenSSL documentation, the file name defaults to * first the RANDFILE environment variable in the user's home directory * and then .rnd in the user's home directory. */#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <string.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/stat.h>#include <sys/time.h>#if HAVE_SYS_TYPES_H# include <sys/types.h>#endif#include "ntp_types.h"#include "ntp_random.h"#include "l_stdlib.h"#ifdef SYS_WINNTextern int ntp_getopt P((int, char **, const char *));#define getopt ntp_getopt#define optarg ntp_optarg#endif#ifdef OPENSSL#include "openssl/bn.h"#include "openssl/evp.h"#include "openssl/err.h"#include "openssl/rand.h"#include "openssl/pem.h"#include "openssl/x509v3.h"#include <openssl/objects.h>#endif /* OPENSSL *//* * Cryptodefines */#define MD5KEYS 16 /* number of MD5 keys generated */#define JAN_1970 ULONG_CONST(2208988800) /* NTP seconds */#define YEAR ((long)60*60*24*365) /* one year in seconds */#define MAXFILENAME 256 /* max file name length */#define MAXHOSTNAME 256 /* max host name length */#ifdef OPENSSL#define PLEN 512 /* default prime modulus size (bits) *//* * Strings used in X509v3 extension fields */#define KEY_USAGE "digitalSignature,keyCertSign"#define BASIC_CONSTRAINTS "critical,CA:TRUE"#define EXT_KEY_PRIVATE "private"#define EXT_KEY_TRUST "trustRoot"#endif /* OPENSSL *//* * Prototypes */FILE *fheader P((const char *, const char *));void fslink P((const char *, const char *));int gen_md5 P((char *));#ifdef OPENSSLEVP_PKEY *gen_rsa P((char *));EVP_PKEY *gen_dsa P((char *));EVP_PKEY *gen_iff P((char *));EVP_PKEY *gen_gqpar P((char *));EVP_PKEY *gen_gqkey P((char *, EVP_PKEY *));EVP_PKEY *gen_mv P((char *));int x509 P((EVP_PKEY *, const EVP_MD *, char *, char *));void cb P((int, int, void *));EVP_PKEY *genkey P((char *, char *));u_long asn2ntp P((ASN1_TIME *));#endif /* OPENSSL *//* * Program variables */extern char *optarg; /* command line argument */int debug = 0; /* debug, not de bug */int rval; /* return status */#ifdef OPENSSLu_int modulus = PLEN; /* prime modulus size (bits) */#endifint nkeys = 0; /* MV keys */time_t epoch; /* Unix epoch (seconds) since 1970 */char *hostname; /* host name (subject name) */char *trustname; /* trusted host name (issuer name) */char filename[MAXFILENAME + 1]; /* file name */char *passwd1 = NULL; /* input private key password */char *passwd2 = NULL; /* output private key password */#ifdef OPENSSLlong d0, d1, d2, d3; /* callback counters */#endif /* OPENSSL */#ifdef SYS_WINNTBOOL init_randfile();/* * Don't try to follow symbolic links */intreadlink(char * link, char * file, int len) { return (-1);}/* * Don't try to create a symbolic link for now. * Just move the file to the name you need. */intsymlink(char *filename, char *linkname) { DeleteFile(linkname); MoveFile(filename, linkname); return 0;}voidInitWin32Sockets() { WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(2,0); if (WSAStartup(wVersionRequested, &wsaData)) { fprintf(stderr, "No useable winsock.dll"); exit(1); }}#endif /* SYS_WINNT *//* * Main program */intmain( int argc, /* command line options */ char **argv ){ int errflg = 0; struct timeval tv; /* initialization vector */#ifdef OPENSSL X509 *cert = NULL; /* X509 certificate */ EVP_PKEY *pkey_host = NULL; /* host key */ EVP_PKEY *pkey_sign = NULL; /* sign key */ EVP_PKEY *pkey_iff = NULL; /* IFF parameters */ EVP_PKEY *pkey_gq = NULL; /* GQ parameters */ EVP_PKEY *pkey_mv = NULL; /* MV parameters */#endif int md5key = 0; /* generate MD5 keys */#ifdef OPENSSL int hostkey = 0; /* generate RSA keys */ int iffkey = 0; /* generate IFF parameters */ int gqpar = 0; /* generate GQ parameters */ int gqkey = 0; /* update GQ keys */ int mvpar = 0; /* generate MV parameters */ int mvkey = 0; /* update MV keys */ char *sign = NULL; /* sign key */ EVP_PKEY *pkey = NULL; /* temp key */ const EVP_MD *ectx; /* EVP digest */ char pathbuf[MAXFILENAME + 1]; const char *scheme = NULL; /* digest/signature scheme */ char *exten = NULL; /* private extension */ char *grpkey = NULL; /* identity extension */ int nid; /* X509 digest/signature scheme */ FILE *fstr = NULL; /* file handle */ int iffsw = 0; /* IFF key switch */#endif /* OPENSSL */ char hostbuf[MAXHOSTNAME + 1]; u_int temp;#ifdef SYS_WINNT /* Initialize before OpenSSL checks */ InitWin32Sockets(); if(!init_randfile()) fprintf(stderr, "Unable to initialize .rnd file\n");#endif#ifdef OPENSSL /* * OpenSSL version numbers: MNNFFPPS: major minor fix patch status * We match major, minor, fix and status (not patch) */ if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L) { fprintf(stderr, "OpenSSL version mismatch. Built against %lx, you have %lx\n", OPENSSL_VERSION_NUMBER, SSLeay()); return (-1); } else { fprintf(stderr, "Using OpenSSL version %lx\n", SSLeay()); }#endif /* OPENSSL */ /* * Process options, initialize host name and timestamp. */ gethostname(hostbuf, MAXHOSTNAME); hostname = hostbuf;#ifdef OPENSSL trustname = hostbuf; passwd1 = hostbuf;#endif#ifndef SYS_WINNT gettimeofday(&tv, 0);#else gettimeofday(&tv);#endif epoch = tv.tv_sec; rval = 0; while ((temp = getopt(argc, argv,#ifdef OPENSSL "c:deGgHIi:Mm:nPp:q:S:s:TV:v:"#else "dM"#endif )) != -1) { switch(temp) {#ifdef OPENSSL /* * -c select public certificate type */ case 'c': scheme = optarg; continue;#endif /* * -d debug */ case 'd': debug++; continue;#ifdef OPENSSL /* * -e write identity keys */ case 'e': iffsw++; continue;#endif#ifdef OPENSSL /* * -G generate GQ parameters and keys */ case 'G': gqpar++; continue;#endif#ifdef OPENSSL /* * -g update GQ keys */ case 'g': gqkey++; continue;#endif#ifdef OPENSSL /* * -H generate host key (RSA) */ case 'H': hostkey++; continue;#endif#ifdef OPENSSL /* * -I generate IFF parameters */ case 'I': iffkey++; continue;#endif#ifdef OPENSSL /* * -i set issuer name */ case 'i': trustname = optarg; continue;#endif /* * -M generate MD5 keys */ case 'M': md5key++; continue;#ifdef OPENSSL /* * -m select modulus (256-2048) */ case 'm': if (sscanf(optarg, "%d", &modulus) != 1) { fprintf(stderr, "invalid option -m %s\n", optarg); ++errflg; } continue;#endif#ifdef OPENSSL /* * -P generate PC private certificate */ case 'P': exten = EXT_KEY_PRIVATE; continue;#endif#ifdef OPENSSL /* * -p output private key password */ case 'p': passwd2 = optarg; continue;#endif#ifdef OPENSSL /* * -q input private key password */ case 'q': passwd1 = optarg; continue;#endif#ifdef OPENSSL /* * -S generate sign key (RSA or DSA) */ case 'S': sign = optarg; continue;#endif#ifdef OPENSSL /* * -s set subject name */ case 's': hostname = optarg; continue;#endif#ifdef OPENSSL /* * -T trusted certificate (TC scheme) */ case 'T': exten = EXT_KEY_TRUST; continue;#endif#ifdef OPENSSL /* * -V <keys> generate MV parameters */ case 'V': mvpar++; if (sscanf(optarg, "%d", &nkeys) != 1) { fprintf(stderr, "invalid option -V %s\n", optarg); ++errflg; } continue;#endif#ifdef OPENSSL /* * -v <key> update MV keys */ case 'v': mvkey++; if (sscanf(optarg, "%d", &nkeys) != 1) { fprintf(stderr, "invalid option -v %s\n", optarg); ++errflg; } continue;#endif /* * None of the above. */ default: ++errflg; continue; } } if (errflg) { printf("Usage: ntp-keygen [options]\n"); printf("where options are:\n");#ifdef OPENSSL printf(" -c cert_scheme\n");#endif printf(" -d increase debug level\n");#ifdef OPENSSL printf(" -e Write identity keys\n"); printf(" -G Generate GQ parameters and keys\n"); printf(" -g Update GQ keys\n"); printf(" -H Generate RSA Host key\n"); printf(" -I Generate IFF parameters\n"); printf(" -i issuer_name\n");#endif printf(" -M Generate MD5 keys\n");#ifdef OPENSSL printf(" -m modulus 256 - 2048\n"); printf(" -P generate PC private certificate\n"); printf(" -p output_pass output private password\n"); printf(" -q input_pass input private password\n"); printf(" -S sign-key generate sign key (RSA or DSA)\n"); printf(" -s set-subj-name\n"); printf(" -T Trusted certificate (TC scheme)\n"); printf(" -V #keys generate MV parameters\n"); printf(" -v #keys update MV parameters\n"); printf("\n"); printf("If there is no new host key, look for an existing one.\n"); printf("If one is not found, create it.\n");#endif exit(2); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -