Ejemplo n.º 1
0
void calculate_rsa_ckaid(osw_public_key *pub)
{
    if(pub->alg == PUBKEY_ALG_RSA) {
        struct RSA_public_key *rsa = &pub->u.rsa;

        if(rsa->key_rfc3110.len == 0) {
            /* key has no 3110 representation, need to cons up one */
            unsigned int e_size     = mpz_sizeinbase(&rsa->e, 256);
            unsigned int key3110len = rsa->k + 1 + e_size;
            rsa->key_rfc3110.ptr = alloc_bytes(key3110len, "rfc3110 format of public key [created]");
            rsa->key_rfc3110.len = key3110len;
            unsigned char *here = rsa->key_rfc3110.ptr;

            here[0] = e_size;
            here++;
            mpz_export(here, NULL, 1, 1, 1, 0, &rsa->e);
            here += e_size;
            mpz_export(here, NULL, 1, 1, 1, 0, &rsa->n);
        }

        /* maybe #ifdef SHA2 ? */
        /* calculate the hash of the public key, using SHA-2 */
        sha256_hash_buffer(rsa->key_rfc3110.ptr, rsa->key_rfc3110.len,
                           pub->key_ckaid, sizeof(pub->key_ckaid));

        datatot(pub->key_ckaid, sizeof(pub->key_ckaid), 'G',
                pub->key_ckaid_print_buf, sizeof(pub->key_ckaid_print_buf));
    }
}
Ejemplo n.º 2
0
Archivo: x509.c Proyecto: mkj/libreswan
/*
 * check if any crls are about to expire
 */
void check_crls(void)
{
	x509crl_t *crl;

	lock_crl_list("check_crls");
	crl = x509crls;

	while (crl != NULL) {
		deltatime_t time_left = realtimediff(crl->nextUpdate, realnow());
		char buf[ASN1_BUF_LEN];

		DBG(DBG_X509, {
			    dntoa(buf, ASN1_BUF_LEN, crl->issuer);
			    DBG_log("issuer: '%s'", buf);
			    if (crl->authKeyID.ptr != NULL) {
				    datatot(crl->authKeyID.ptr,
					    crl->authKeyID.len, ':',
					    buf, ASN1_BUF_LEN);
				    DBG_log("authkey: %s", buf);
			    }
			    DBG_log("%ld seconds left", (long)deltasecs(time_left));
		    });
		if (deltaless(time_left, deltatimescale(2, 1, crl_check_interval)))
			add_crl_fetch_request(crl->issuer,
					      crl->distributionPoints);
		crl = crl->next;
	}
Ejemplo n.º 3
0
/*
 * check if any crls are about to expire
 */
void
check_crls(void)
{
#ifdef HAVE_THREADS
    x509crl_t *crl;
    time_t current_time = time(NULL);

    lock_crl_list("check_crls");
    crl = x509crls;

    while (crl != NULL)
    {
	time_t time_left = crl->nextUpdate - current_time;
	u_char buf[ASN1_BUF_LEN];

	DBG(DBG_X509,
	    dntoa(buf, ASN1_BUF_LEN, crl->issuer);
	    DBG_log("issuer: '%s'",buf);
	    if (crl->authKeyID.ptr != NULL)
	    {
		datatot(crl->authKeyID.ptr, crl->authKeyID.len, ':'
		    , buf, ASN1_BUF_LEN);
		DBG_log("authkey: %s", buf);
	    }
	    DBG_log("%ld seconds left", time_left)
	)
	if (time_left < 2*crl_check_interval)
	    add_crl_fetch_request(crl->issuer, crl->distributionPoints);
	crl = crl->next;
    }
    unlock_crl_list("check_crls");
#endif
}
Ejemplo n.º 4
0
/* generate a transaction id as the MD5 hash of an public key
 * the transaction id is also used as a unique serial number
 */
void
scep_generate_transaction_id(const RSA_public_key_t *rsak
, chunk_t *transID, chunk_t *serialNumber)
{
    char buf[MD5_DIGEST_SIZE];

    chunk_t digest = { buf, sizeof(buf) };
    chunk_t public_key = pkcs1_build_publicKeyInfo(rsak);

    bool msb_set;
    u_char *pos;

    compute_digest(public_key, OID_MD5, &digest);
    pfree(public_key.ptr);

    /* is the most significant bit of the digest set? */
    msb_set = (*digest.ptr & 0x80) == 0x80;

    /* allocate space for the serialNumber */
    serialNumber->len = msb_set + digest.len;
    serialNumber->ptr = alloc_bytes(serialNumber->len, "serialNumber");

    /* the serial number as the two's complement of the digest */
    pos = serialNumber->ptr;
    if (msb_set)
    {
	*pos++ = 0x00;
    }
    memcpy(pos, digest.ptr, digest.len);

    /* the transaction id is the serial number in hex format */
    transID->len = 2*digest.len;
    transID->ptr = alloc_bytes(transID->len + 1, "transID");
    datatot(digest.ptr, digest.len, 16, transID->ptr, transID->len + 1);
}
Ejemplo n.º 5
0
/*
 * check if an ocsp status is about to expire
 */
void
check_ocsp(void)
{
    ocsp_location_t *location;

    lock_ocsp_cache("check_ocsp");
    location = ocsp_cache;
    
    while (location != NULL)
    {
	char buf[BUF_LEN];
	bool first = TRUE;
	ocsp_certinfo_t *certinfo = location->certinfo;

	while (certinfo != NULL)
	{
	    if (!certinfo->once)
	    {
		time_t time_left = certinfo->nextUpdate - time(NULL);

		DBG(DBG_CONTROL,
		    if (first)
		    {
			dntoa(buf, BUF_LEN, location->issuer);
			DBG_log("issuer: '%s'", buf);
			if (location->authKeyID.ptr != NULL)
			{
			    datatot(location->authKeyID.ptr, location->authKeyID.len
				, ':', buf, BUF_LEN);
			    DBG_log("authkey: %s", buf);
			}
			first = FALSE;
		    }
		    datatot(certinfo->serialNumber.ptr, certinfo->serialNumber.len
			, ':', buf, BUF_LEN);
		    DBG_log("serial: %s, %ld seconds left", buf, time_left)
		)

#ifdef HAVE_THREADS
		if (time_left < 2*crl_check_interval)
		    add_ocsp_fetch_request(location, certinfo->serialNumber);
#endif
	    }
	    certinfo = certinfo->next;
	}
	location = location->next;
    }
Ejemplo n.º 6
0
/* converts a binary request to base64 with 64 characters per line
 * newline and '+' characters are escaped by %0A and %2B, respectively
 */
static char*
escape_http_request(chunk_t req)
{
    char *escaped_req = NULL;
    char *p1, *p2;
    int lines = 0;
    int plus  = 0;
    int n     = 0;

    /* compute and allocate the size of the base64-encoded request */
    int len = 1 + 4*((req.len + 2)/3);
    char *encoded_req = alloc_bytes(len, "encoded request");

    /* do the base64 conversion */
    len = datatot(req.ptr, req.len, 64, encoded_req, len);

    /* compute newline characters to be inserted every 64 characters */
    lines = (len - 2) / 64;

    /* count number of + characters to be escaped */
    p1 = encoded_req;
    while (*p1 != '\0')
    {
	if (*p1++ == '+')
	    plus++;
    }

    escaped_req = alloc_bytes(len + 3*(lines + plus), "escaped request");

    /* escape special characters in the request */
    p1 = encoded_req;
    p2 = escaped_req;
    while (*p1 != '\0')
    {
	if (n == 64)
	{
	    memcpy(p2, "%0A", 3);
	    p2 += 3;
	    n = 0;
	}
	if (*p1 == '+')
	{
	    memcpy(p2, "%2B", 3);
	    p2 += 3;
	}
	else
	{
	    *p2++ = *p1;
	}
	p1++;
	n++;
    }
    *p2 = '\0';
    pfreeany(encoded_req);
    return escaped_req;
}
Ejemplo n.º 7
0
static void print(struct private_key_stuff *pks,
		  int count, struct id *id, bool disclose)
{
	char idb[IDTOA_BUF] = "n/a";
	if (id) {
		idtoa(id, idb, IDTOA_BUF);
	}

	char pskbuf[128] = "";
	if (pks->kind == PPK_PSK || pks->kind == PPK_XAUTH) {
		datatot(pks->u.preshared_secret.ptr,
			pks->u.preshared_secret.len,
			'x', pskbuf, sizeof(pskbuf));
	}

	if (count) {
		/* ipsec.secrets format */
		printf("%d(%d): ", pks->line, count);
	} else {
		/* NSS format */
		printf("<%2d> ", pks->line);
	}

	switch (pks->kind) {
	case PPK_PSK:
		printf("PSK keyid: %s\n", idb);
		if (disclose)
			printf("    psk: \"%s\"\n", pskbuf);
		break;

	case PPK_RSA: {
		printf("RSA");
		char *keyid = pks->u.RSA_private_key.pub.keyid;
		printf(" keyid: %s", keyid[0] ? keyid : "<missing-pubkey>");
		if (id) {
			printf(" id: %s", idb);
		}
		char *ckaid = ckaid_as_string(pks->u.RSA_private_key.pub.ckaid);
		printf(" ckaid: %s\n", ckaid);
		pfree(ckaid);
		break;
	}

	case PPK_XAUTH:
		printf("XAUTH keyid: %s\n", idb);
		if (disclose)
			printf("    xauth: \"%s\"\n", pskbuf);
		break;
	case PPK_NULL:
		/* can't happen but the compiler does not know that */
		printf("NULL authentication -- cannot happen: %s\n", idb);
		abort();
	}
}
Ejemplo n.º 8
0
/* generates a unique fingerprint of the pkcs10 request 
 * by computing an MD5 hash over it
 */
void
scep_generate_pkcs10_fingerprint(chunk_t pkcs10, chunk_t *fingerprint)
{
    char buf[MD5_DIGEST_SIZE];
    chunk_t digest = { buf, sizeof(buf) };

    /* the fingerprint is the MD5 hash in hexadecimal format */
    compute_digest(pkcs10, OID_MD5, &digest);
    fingerprint->len = 2*digest.len;
    fingerprint->ptr = alloc_bytes(fingerprint->len + 1, "fingerprint");
    datatot(digest.ptr, digest.len, 16, fingerprint->ptr, fingerprint->len + 1);
}
Ejemplo n.º 9
0
int print_key(struct secret *secret
	      , struct private_key_stuff *pks
	      , void *uservoid, bool disclose)
{
    int lineno = osw_get_secretlineno(secret);
    struct id_list *l = osw_get_idlist(secret);
    char idb[IDTOA_BUF];
    int count=1;

    char pskbuf[128];

    if(pks->kind == PPK_PSK || pks->kind==PPK_XAUTH) {
	datatot(pks->u.preshared_secret.ptr,
		pks->u.preshared_secret.len,
		'x', pskbuf, sizeof(pskbuf));
    }

    while(l) {
	idtoa(&l->id, idb, IDTOA_BUF);

	switch(pks->kind) {
	case PPK_PSK:
	    printf("%d(%d): PSK keyid: %s\n", lineno, count, idb);
	    if(disclose) printf("    psk: \"%s\"\n", pskbuf);
	    break;
	    
	case PPK_RSA:
	    printf("%d(%d): RSA keyid: %s with id: %s\n", lineno, count, pks->u.RSA_private_key.pub.keyid,idb);
	    break;
	    
	case PPK_XAUTH:
	    printf("%d(%d): XAUTH keyid: %s\n", lineno, count, idb);
	    if(disclose) printf("    xauth: \"%s\"\n", pskbuf);
	    break;
	    
	case PPK_PIN:
	    printf("%d:(%d) PIN key-type not yet supported for id: %s\n", lineno, count, idb);
	    break;
	}
	
	l=l->next;
	count++;
    }
    
    return 1;
}
Ejemplo n.º 10
0
/*
   - conv - convert bits to output in specified datatot format
 * NOTE: result points into a STATIC buffer
 */
static const char *conv(const unsigned char *bits, size_t nbytes, int format)
{
	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;
}
Ejemplo n.º 11
0
/**
 * Generate a transaction id as the MD5 hash of an public key
 * the transaction id is also used as a unique serial number
 */
void scep_generate_transaction_id(public_key_t *key, chunk_t *transID,
								  chunk_t *serialNumber)
{
	chunk_t digest = chunk_alloca(HASH_SIZE_MD5);
	chunk_t keyEncoding = chunk_empty, keyInfo;
	hasher_t *hasher;
	bool msb_set;
	u_char *pos;

	key->get_encoding(key, KEY_PUB_ASN1_DER, &keyEncoding);

	keyInfo = asn1_wrap(ASN1_SEQUENCE, "mm",
						asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
						asn1_bitstring("m", keyEncoding));

	hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
	hasher->get_hash(hasher, keyInfo, digest.ptr);
	hasher->destroy(hasher);
	free(keyInfo.ptr);

	/* is the most significant bit of the digest set? */
	msb_set = (*digest.ptr & 0x80) == 0x80;

	/* allocate space for the serialNumber */
	serialNumber->len = msb_set + digest.len;
	serialNumber->ptr = malloc(serialNumber->len);

	/* the serial number as the two's complement of the digest */
	pos = serialNumber->ptr;
	if (msb_set)
	{
		*pos++ = 0x00;
	}
	memcpy(pos, digest.ptr, digest.len);

	/* the transaction id is the serial number in hex format */
	transID->len = 2*digest.len;
	transID->ptr = malloc(transID->len + 1);
	datatot(digest.ptr, digest.len, 16, transID->ptr, transID->len + 1);
}
Ejemplo n.º 12
0
/*
 * 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.
 * See also: https://www.imperialviolet.org/2012/03/16/rsae.html
 */
void rsasigkey(int nbits, int seedbits, const struct lsw_conf_options *oco)
{
	PK11RSAGenParams rsaparams = { nbits, (long) F4 };
	PK11SlotInfo *slot = NULL;
	SECKEYPrivateKey *privkey = NULL;
	SECKEYPublicKey *pubkey = NULL;
	realtime_t now = realnow();

	lsw_nss_buf_t err;
	if (!lsw_nss_setup(oco->nssdir, 0, lsw_nss_get_password, err)) {
		fprintf(stderr, "%s: %s\n", progname, err);
		exit(1);
	}

#ifdef FIPS_CHECK
	if (PK11_IsFIPS() && !FIPSCHECK_verify(NULL, NULL)) {
		fprintf(stderr,
			"FIPS HMAC integrity verification test failed.\n");
		exit(1);
	}
#endif

	/* Good for now but someone may want to use a hardware token */
	slot = lsw_nss_get_authenticated_slot(err);
	if (slot == NULL) {
		fprintf(stderr, "%s: %s\n", progname, err);
		lsw_nss_shutdown();
		exit(1);
	}

	/* Do some random-number initialization. */
	UpdateNSS_RNG(seedbits);
	privkey = PK11_GenerateKeyPair(slot,
				       CKM_RSA_PKCS_KEY_PAIR_GEN,
				       &rsaparams, &pubkey,
				       PR_TRUE,
				       PK11_IsFIPS() ? PR_TRUE : PR_FALSE,
				       lsw_return_nss_password_file_info());
	/* inTheToken, isSensitive, passwordCallbackFunction */
	if (privkey == NULL) {
		fprintf(stderr,
			"%s: key pair generation failed: \"%d\"\n", progname,
			PORT_GetError());
		return;
	}

	chunk_t public_modulus = {
		.ptr = pubkey->u.rsa.modulus.data,
		.len = pubkey->u.rsa.modulus.len,
	};
	chunk_t public_exponent = {
		.ptr = pubkey->u.rsa.publicExponent.data,
		.len = pubkey->u.rsa.publicExponent.len,
	};

	char *hex_ckaid;
	{
		SECItem *ckaid = PK11_GetLowLevelKeyIDForPrivateKey(privkey);
		if (ckaid == NULL) {
			fprintf(stderr, "%s: 'CKAID' calculation failed\n", progname);
			exit(1);
		}
		hex_ckaid = strdup(conv(ckaid->data, ckaid->len, 16));
		SECITEM_FreeItem(ckaid, PR_TRUE);
	}

	/*privkey->wincx = &pwdata;*/
	PORT_Assert(pubkey != NULL);
	fprintf(stderr, "Generated RSA key pair with CKAID %s was stored in the NSS database\n",
		hex_ckaid);

	/* and the output */
	libreswan_log("output...\n");  /* deliberate extra newline */
	printf("\t# RSA %d bits   %s   %s", nbits, outputhostname,
		ctime(&now.rt.tv_sec));
	/* ctime provides \n */
	printf("\t# for signatures only, UNSAFE FOR ENCRYPTION\n");

	printf("\t#ckaid=%s\n", hex_ckaid);

	/* RFC2537/RFC3110-ish format */
	{
		char *base64 = NULL;
		err_t err = rsa_pubkey_to_base64(public_exponent, public_modulus, &base64);
		if (err) {
			fprintf(stderr, "%s: unexpected error encoding RSA public key '%s'\n",
				progname, err);
			exit(1);
		}
		printf("\t#pubkey=%s\n", base64);
		pfree(base64);
	}

	printf("\tModulus: 0x%s\n", conv(public_modulus.ptr, public_modulus.len, 16));
	printf("\tPublicExponent: 0x%s\n", conv(public_exponent.ptr, public_exponent.len, 16));

	if (hex_ckaid != NULL)
		free(hex_ckaid);
	if (privkey != NULL)
		SECKEY_DestroyPrivateKey(privkey);
	if (pubkey != NULL)
		SECKEY_DestroyPublicKey(pubkey);

	lsw_nss_shutdown();
}

/*
 * lsw_random - get some random bytes from /dev/random (or wherever)
 * NOTE: This is only used for additional seeding of the NSS RNG
 */
void lsw_random(size_t nbytes, unsigned char *buf)
{
	size_t ndone;
	int dev;
	ssize_t got;

	dev = open(device, 0);
	if (dev < 0) {
		fprintf(stderr, "%s: could not open %s (%s)\n", progname,
			device, strerror(errno));
		exit(1);
	}

	ndone = 0;
	libreswan_log("getting %d random seed bytes for NSS from %s...\n",
		      (int) nbytes * BITS_PER_BYTE, device);
	while (ndone < nbytes) {
		got = read(dev, buf + ndone, nbytes - ndone);
		if (got < 0) {
			fprintf(stderr, "%s: read error on %s (%s)\n", progname,
				device, strerror(errno));
			exit(1);
		}
		if (got == 0) {
			fprintf(stderr, "%s: eof on %s!?!\n", progname, device);
			exit(1);
		}
		ndone += got;
	}

	close(dev);
}

/*
   - conv - convert bits to output in specified datatot format
 * NOTE: result points into a STATIC buffer
 */
static const char *conv(const unsigned char *bits, size_t nbytes, int format)
{
	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", progname);
		exit(1);
	}
	if (n > sizeof(convbuf)) {
		fprintf(stderr,
			"%s: can't-happen convert overflow (need %d)\n",
			progname, (int) n);
		exit(1);
	}
	return convbuf;
}
Ejemplo n.º 13
0
/*
 *  Converts a binary key ID into hexadecimal format
 */
static int
keyidtoa(char *dst, size_t dstlen, chunk_t keyid)
{
    int n = datatot(keyid.ptr, keyid.len, 'x', dst, dstlen);
    return ((n < (int)dstlen)? n : (int)dstlen) - 1;
}
Ejemplo n.º 14
0
/*
 * 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.
 * See also: https://www.imperialviolet.org/2012/03/16/rsae.html
 */
void rsasigkey(int nbits, int seedbits, char *configdir, char *password)
{
	SECStatus rv;
	PK11RSAGenParams rsaparams = { nbits, (long) E };
	secuPWData pwdata = { PW_NONE, NULL };
	PK11SlotInfo *slot = NULL;
	SECKEYPrivateKey *privkey = NULL;
	SECKEYPublicKey *pubkey = NULL;
	realtime_t now = realnow();

	if (password == NULL) {
		pwdata.source = PW_NONE;
	} else {
		/* check if passwd == configdir/nsspassword */
		size_t cdl = strlen(configdir);
		size_t pwl = strlen(password);
		static const char suf[] = "/nsspassword";

		if (pwl == cdl + sizeof(suf) - 1 &&
			memeq(password, configdir, cdl) &&
			memeq(password + cdl, suf, sizeof(suf)))
			pwdata.source = PW_FROMFILE;
		else
			pwdata.source = PW_PLAINTEXT;
	}
	pwdata.data = password;

	lsw_nss_buf_t err;
	if (!lsw_nss_setup(configdir, FALSE/*rw*/, GetModulePassword, err)) {
		fprintf(stderr, "%s: %s\n", me, err);
		exit(1);
	}

#ifdef FIPS_CHECK
	if (PK11_IsFIPS() && !FIPSCHECK_verify(NULL, NULL)) {
		fprintf(stderr,
			"FIPS HMAC integrity verification test failed.\n");
		exit(1);
	}
#endif

	if (PK11_IsFIPS() && password == NULL) {
		fprintf(stderr,
			"%s: On FIPS mode a password is required\n",
			me);
		exit(1);
	}

	/* Good for now but someone may want to use a hardware token */
	slot = PK11_GetInternalKeySlot();
	/* In which case this may be better */
	/* slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN, password ? &pwdata : NULL); */
	/* or the user may specify the name of a token. */

#if 0
	if (PK11_IsFIPS() || !PK11_IsInternal(slot)) {
		rv = PK11_Authenticate(slot, PR_FALSE, &pwdata);
		if (rv != SECSuccess) {
			fprintf(stderr, "%s: could not authenticate to token '%s'\n",
				me, PK11_GetTokenName(slot));
			return;
		}
	}
#endif /* 0 */

	/* Do some random-number initialization. */
	UpdateNSS_RNG(seedbits);
	/* Log in to the token */
	if (password != NULL) {
		rv = PK11_Authenticate(slot, PR_FALSE, &pwdata);
		if (rv != SECSuccess) {
			fprintf(stderr,
				"%s: could not authenticate to token '%s'\n",
				me, PK11_GetTokenName(slot));
			return;
		}
	}
	privkey = PK11_GenerateKeyPair(slot,
				       CKM_RSA_PKCS_KEY_PAIR_GEN,
				       &rsaparams, &pubkey,
				       PR_TRUE,
				       password != NULL? PR_TRUE : PR_FALSE,
				       &pwdata);
	/* inTheToken, isSensitive, passwordCallbackFunction */
	if (privkey == NULL) {
		fprintf(stderr,
			"%s: key pair generation failed: \"%d\"\n", me,
			PORT_GetError());
		return;
	}

	chunk_t public_modulus = {
		.ptr = pubkey->u.rsa.modulus.data,
		.len = pubkey->u.rsa.modulus.len,
	};
	chunk_t public_exponent = {
		.ptr = pubkey->u.rsa.publicExponent.data,
		.len = pubkey->u.rsa.publicExponent.len,
	};

	char *hex_ckaid;
	{
		SECItem *ckaid = PK11_GetLowLevelKeyIDForPrivateKey(privkey);
		if (ckaid == NULL) {
			fprintf(stderr, "%s: 'CKAID' calculation failed\n", me);
			exit(1);
		}
		hex_ckaid = strdup(conv(ckaid->data, ckaid->len, 16));
		SECITEM_FreeItem(ckaid, PR_TRUE);
	}

	/*privkey->wincx = &pwdata;*/
	PORT_Assert(pubkey != NULL);
	fprintf(stderr, "Generated RSA key pair with CKAID %s was stored in the NSS database\n",
		hex_ckaid);

	/* and the output */
	report("output...\n");  /* deliberate extra newline */
	printf("\t# RSA %d bits   %s   %s", nbits, outputhostname,
		ctime(&now.real_secs));
	/* ctime provides \n */
	printf("\t# for signatures only, UNSAFE FOR ENCRYPTION\n");

	printf("\t#ckaid=%s\n", hex_ckaid);

	/* RFC2537/RFC3110-ish format */
	{
		char *bundle = base64_bundle(E, public_modulus);
		printf("\t#pubkey=%s\n", bundle);
		pfree(bundle);
	}

	printf("\tModulus: 0x%s\n", conv(public_modulus.ptr, public_modulus.len, 16));
	printf("\tPublicExponent: 0x%s\n", conv(public_exponent.ptr, public_exponent.len, 16));

	if (hex_ckaid != NULL)
		free(hex_ckaid);
	if (privkey != NULL)
		SECKEY_DestroyPrivateKey(privkey);
	if (pubkey != NULL)
		SECKEY_DestroyPublicKey(pubkey);

	lsw_nss_shutdown(LSW_NSS_CLEANUP);
}

/*
 * getrandom - get some random bytes from /dev/random (or wherever)
 * NOTE: This is only used for additional seeding of the NSS RNG
 */
void getrandom(size_t nbytes, unsigned char *buf)
{
	size_t ndone;
	int dev;
	ssize_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 seed bytes for NSS from %s...\n",
			(int) nbytes * BITS_PER_BYTE,
			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);
}

/*
   - conv - convert bits to output in specified datatot format
 * NOTE: result points into a STATIC buffer
 */
static const char *conv(const unsigned char *bits, size_t nbytes, int format)
{
	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);
}
Ejemplo n.º 15
0
/* x509.c SEAM */
static void
list_x509cert_chain(const char *caption, x509cert_t* cert, u_char auth_flags
 , bool utc)
{
    bool first = TRUE;
    time_t tnow;

    /* determine the current time */
    time(&tnow);

    while (cert != NULL)
    {
	if (auth_flags == AUTH_NONE || (auth_flags & cert->authority_flags))
	{
	    unsigned keysize;
	    char keyid[KEYID_BUF];
	    char buf[ASN1_BUF_LEN];
	    char tbuf[TIMETOA_BUF];

	    cert_t c;

	    c.type = CERT_X509_SIGNATURE;
	    c.u.x509 = cert;

	    if (first)
	    {
		DBG_log( " ");
		DBG_log( "List of X.509 %s Certificates:", caption);
		DBG_log( " ");
		first = FALSE;
	    }

	    DBG_log( "NOW, count: %d", cert->count);
	    dntoa(buf, ASN1_BUF_LEN, cert->subject);
	    DBG_log( "       subject: '%s'", buf);
	    dntoa(buf, ASN1_BUF_LEN, cert->issuer);
	    DBG_log( "       issuer:  '%s'", buf);
	    datatot(cert->serialNumber.ptr, cert->serialNumber.len, ':'
		, buf, ASN1_BUF_LEN);
	    DBG_log( "       serial:   %s", buf);
	    form_keyid(cert->publicExponent, cert->modulus, keyid, &keysize);
	    DBG_log( "       pubkey:   %4d RSA Key %s"
                    , 8*keysize, keyid);
	    DBG_log( "       validity: not before %s %s",
		timetoa(&cert->notBefore, utc, tbuf, sizeof(tbuf)),
		(cert->notBefore < tnow)?"ok":"fatal (not valid yet)");
	    DBG_log( "                 not after  %s %s",
		timetoa(&cert->notAfter, utc, tbuf, sizeof(tbuf)),
		check_expiry(cert->notAfter, CA_CERT_WARNING_INTERVAL, TRUE));
	    if (cert->subjectKeyID.ptr != NULL)
	    {
		datatot(cert->subjectKeyID.ptr, cert->subjectKeyID.len, ':'
		    , buf, ASN1_BUF_LEN);
		DBG_log( "       subjkey:  %s", buf);
	    }
	    if (cert->authKeyID.ptr != NULL)
	    {
		datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
		    , buf, ASN1_BUF_LEN);
		DBG_log( "       authkey:  %s", buf);
	    }
	    if (cert->authKeySerialNumber.ptr != NULL)
	    {
		datatot(cert->authKeySerialNumber.ptr, cert->authKeySerialNumber.len
		    , ':', buf, ASN1_BUF_LEN);
		DBG_log( "       aserial:  %s", buf);
	    }
	}
	cert = cert->next;
    }
}
Ejemplo n.º 16
0
/* establish trust into a candidate authcert by going up the trust chain.
 * validity and revocation status are not checked.
 */
bool
trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chain)
{
    int pathlen;

    lock_authcert_list("trust_authcert_candidate");

    for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
    {
       const x509cert_t *authcert = NULL;

       DBG(DBG_CONTROL,
           char buf[ASN1_BUF_LEN];
           dntoa(buf, ASN1_BUF_LEN, cert->subject);
           DBG_log("subject: '%s'",buf);
           dntoa(buf, ASN1_BUF_LEN, cert->issuer);
           DBG_log("issuer:  '%s'",buf);
           if (cert->authKeyID.ptr != NULL)
           {
               datatot(cert->authKeyID.ptr, cert->authKeyID.len, ':'
                   , buf, ASN1_BUF_LEN);
               DBG_log("authkey:  %s", buf);
           }
	   );

       /* search in alternative chain first */
       authcert = get_alt_cacert(cert->issuer, cert->authKeySerialNumber
           , cert->authKeyID, alt_chain);

       if (authcert != NULL)
       {
           DBG(DBG_CONTROL,
               DBG_log("issuer cacert found in alternative chain")
           )
       }
       else
       {
           /* search in trusted chain */
           authcert = get_authcert(cert->issuer, cert->authKeySerialNumber
               , cert->authKeyID, AUTH_CA);

           if (authcert != NULL)
           {
               DBG(DBG_CONTROL,
                   DBG_log("issuer cacert found")
               )
           }
           else
           {
               plog("issuer cacert not found");
               unlock_authcert_list("trust_authcert_candidate");
               return FALSE;
           }
       }

       if (!check_signature(cert->tbsCertificate, cert->signature,
                            cert->algorithm, authcert))
       {
           plog("invalid certificate signature");
           unlock_authcert_list("trust_authcert_candidate");
           return FALSE;
       }
       DBG(DBG_CONTROL,
           DBG_log("valid certificate signature")
       )

       /* check if cert is a self-signed root ca */
       if (pathlen > 0 && same_dn(cert->issuer, cert->subject))
       {
           DBG(DBG_CONTROL,
               DBG_log("reached self-signed root ca")
           )
           unlock_authcert_list("trust_authcert_candidate");
           return TRUE;
       }

       /* go up one step in the trust chain */
       cert = authcert;
    }