示例#1
0
/* add a key to a secret keyring */
int
__ops_add_to_secring(__ops_keyring_t *keyring, const __ops_seckey_t *seckey)
{
	const __ops_pubkey_t	*pubkey;
	__ops_key_t		*key;

	if (__ops_get_debug_level(__FILE__)) {
		fprintf(stderr, "__ops_add_to_secring\n");
	}
	if (keyring->keyc > 0) {
		key = &keyring->keys[keyring->keyc - 1];
		if (__ops_get_debug_level(__FILE__) &&
		    key->key.pubkey.alg == OPS_PKA_DSA &&
		    seckey->pubkey.alg == OPS_PKA_ELGAMAL) {
			fprintf(stderr, "__ops_add_to_secring: found elgamal seckey\n");
		}
	}
	EXPAND_ARRAY(keyring, key);
	key = &keyring->keys[keyring->keyc++];
	(void) memset(key, 0x0, sizeof(*key));
	pubkey = &seckey->pubkey;
	__ops_keyid(key->sigid, OPS_KEY_ID_SIZE, pubkey, keyring->hashtype);
	__ops_fingerprint(&key->sigfingerprint, pubkey, keyring->hashtype);
	key->type = OPS_PTAG_CT_SECRET_KEY;
	key->key.seckey = *seckey;
	if (__ops_get_debug_level(__FILE__)) {
		fprintf(stderr, "__ops_add_to_secring: keyc %u\n", keyring->keyc);
	}
	return 1;
}
示例#2
0
/* return the next key which matches, starting searching at *from */
static const __ops_key_t *
getkeybyname(__ops_io_t *io,
			const __ops_keyring_t *keyring,
			const char *name,
			unsigned *from)
{
	const __ops_key_t	*kp;
	uint8_t			**uidp;
	unsigned    	 	 i = 0;
	__ops_key_t		*keyp;
	unsigned		 savedstart;
	regex_t			 r;
	uint8_t		 	 keyid[OPS_KEY_ID_SIZE + 1];
	size_t          	 len;

	if (!keyring || !name || !from) {
		return NULL;
	}
	len = strlen(name);
	if (__ops_get_debug_level(__FILE__)) {
		(void) fprintf(io->outs, "[%u] name '%s', len %zu\n",
			*from, name, len);
	}
	/* first try name as a keyid */
	(void) memset(keyid, 0x0, sizeof(keyid));
	str2keyid(name, keyid, sizeof(keyid));
	if (__ops_get_debug_level(__FILE__)) {
		hexdump(io->outs, "keyid", keyid, 4);
	}
	savedstart = *from;
	if ((kp = __ops_getkeybyid(io, keyring, keyid, from, NULL)) != NULL) {
		return kp;
	}
	*from = savedstart;
	if (__ops_get_debug_level(__FILE__)) {
		(void) fprintf(io->outs, "regex match '%s' from %u\n",
			name, *from);
	}
	/* match on full name or email address as a NOSUB, ICASE regexp */
	(void) regcomp(&r, name, REG_EXTENDED | REG_ICASE);
	for (keyp = &keyring->keys[*from]; *from < keyring->keyc; *from += 1, keyp++) {
		uidp = keyp->uids;
		for (i = 0 ; i < keyp->uidc; i++, uidp++) {
			if (regexec(&r, (char *)*uidp, 0, NULL, 0) == 0) {
				if (__ops_get_debug_level(__FILE__)) {
					(void) fprintf(io->outs,
						"MATCHED keyid \"%s\" len %" PRIsize "u\n",
					       (char *) *uidp, len);
				}
				regfree(&r);
				return keyp;
			}
		}
	}
	regfree(&r);
	return NULL;
}
示例#3
0
/**
   \ingroup HighLevel_KeyringFind

   \brief Finds key in keyring from its Key ID

   \param keyring Keyring to be searched
   \param keyid ID of required key

   \return Pointer to key, if found; NULL, if not found

   \note This returns a pointer to the key inside the given keyring,
   not a copy.  Do not free it after use.

*/
const __ops_key_t *
__ops_getkeybyid(__ops_io_t *io, const __ops_keyring_t *keyring,
			   const uint8_t *keyid, unsigned *from, __ops_pubkey_t **pubkey)
{
	uint8_t	nullid[OPS_KEY_ID_SIZE];

	(void) memset(nullid, 0x0, sizeof(nullid));
	for ( ; keyring && *from < keyring->keyc; *from += 1) {
		if (__ops_get_debug_level(__FILE__)) {
			hexdump(io->errs, "keyring keyid", keyring->keys[*from].sigid, OPS_KEY_ID_SIZE);
			hexdump(io->errs, "keyid", keyid, OPS_KEY_ID_SIZE);
		}
		if (memcmp(keyring->keys[*from].sigid, keyid, OPS_KEY_ID_SIZE) == 0 ||
		    memcmp(&keyring->keys[*from].sigid[OPS_KEY_ID_SIZE / 2],
				keyid, OPS_KEY_ID_SIZE / 2) == 0) {
			if (pubkey) {
				*pubkey = &keyring->keys[*from].key.pubkey;
			}
			return &keyring->keys[*from];
		}
		if (memcmp(&keyring->keys[*from].encid, nullid, sizeof(nullid)) == 0) {
			continue;
		}
		if (memcmp(&keyring->keys[*from].encid, keyid, OPS_KEY_ID_SIZE) == 0 ||
		    memcmp(&keyring->keys[*from].encid[OPS_KEY_ID_SIZE / 2], keyid, OPS_KEY_ID_SIZE / 2) == 0) {
			if (pubkey) {
				*pubkey = &keyring->keys[*from].enckey;
			}
			return &keyring->keys[*from];
		}
	}
	return NULL;
}
示例#4
0
/* add a key to a public keyring */
int
__ops_add_to_pubring(__ops_keyring_t *keyring, const __ops_pubkey_t *pubkey, __ops_content_enum tag)
{
	__ops_key_t	*key;
	time_t		 duration;

	if (__ops_get_debug_level(__FILE__)) {
		fprintf(stderr, "__ops_add_to_pubring (type %u)\n", tag);
	}
	switch(tag) {
	case OPS_PTAG_CT_PUBLIC_KEY:
		EXPAND_ARRAY(keyring, key);
		key = &keyring->keys[keyring->keyc++];
		duration = key->key.pubkey.duration;
		(void) memset(key, 0x0, sizeof(*key));
		key->type = tag;
		__ops_keyid(key->sigid, OPS_KEY_ID_SIZE, pubkey, keyring->hashtype);
		__ops_fingerprint(&key->sigfingerprint, pubkey, keyring->hashtype);
		key->key.pubkey = *pubkey;
		key->key.pubkey.duration = duration;
		return 1;
	case OPS_PTAG_CT_PUBLIC_SUBKEY:
		/* subkey is not the first */
		key = &keyring->keys[keyring->keyc - 1];
		__ops_keyid(key->encid, OPS_KEY_ID_SIZE, pubkey, keyring->hashtype);
		duration = key->key.pubkey.duration;
		(void) memcpy(&key->enckey, pubkey, sizeof(key->enckey));
		key->enckey.duration = duration;
		return 1;
	default:
		return 0;
	}
}
示例#5
0
static void 
sha224_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
{
	if (__ops_get_debug_level(__FILE__)) {
		hexdump(stderr, "sha224_add", data, length);
	}
	SHA224_Update(hash->data, data, length);
}
示例#6
0
unsigned 
__ops_dsa_verify(const uint8_t *hash, size_t hash_length,
	       const __ops_dsa_sig_t *sig,
	       const __ops_dsa_pubkey_t *dsa)
{
	unsigned	qlen;
	DSA_SIG        *osig;
	DSA            *odsa;
	int             ret;

	osig = DSA_SIG_new();
	osig->r = sig->r;
	osig->s = sig->s;

	odsa = DSA_new();
	odsa->p = dsa->p;
	odsa->q = dsa->q;
	odsa->g = dsa->g;
	odsa->pub_key = dsa->y;

	if (__ops_get_debug_level(__FILE__)) {
		hexdump(stderr, "input hash", hash, hash_length);
		(void) fprintf(stderr, "Q=%d\n", BN_num_bytes(odsa->q));
	}
	if ((qlen = (unsigned)BN_num_bytes(odsa->q)) < hash_length) {
		hash_length = qlen;
	}
	ret = DSA_do_verify(hash, (int)hash_length, osig, odsa);
	if (__ops_get_debug_level(__FILE__)) {
		(void) fprintf(stderr, "ret=%d\n", ret);
	}
	if (ret < 0) {
		(void) fprintf(stderr, "__ops_dsa_verify: DSA verification\n");
		return 0;
	}

	odsa->p = odsa->q = odsa->g = odsa->pub_key = NULL;
	DSA_free(odsa);

	osig->r = osig->s = NULL;
	DSA_SIG_free(osig);

	return (unsigned)ret;
}
示例#7
0
static unsigned 
sha224_finish(__ops_hash_t *hash, uint8_t *out)
{
	SHA224_Final(out, hash->data);
	if (__ops_get_debug_level(__FILE__)) {
		hexdump(stderr, "sha224_finish", out, SHA224_DIGEST_LENGTH);
	}
	free(hash->data);
	hash->data = NULL;
	return SHA224_DIGEST_LENGTH;
}
示例#8
0
static unsigned 
sha1_finish(__ops_hash_t *hash, uint8_t *out)
{
	SHA1_Final(out, hash->data);
	if (__ops_get_debug_level(__FILE__)) {
		hexdump(stderr, "sha1_finish", out, OPS_SHA1_HASH_SIZE);
	}
	free(hash->data);
	hash->data = NULL;
	return OPS_SHA1_HASH_SIZE;
}
示例#9
0
int
__ops_keyring_json(__ops_io_t *io, const __ops_keyring_t *keyring, mj_t *obj, const int psigs)
{
	__ops_key_t		*key;
	unsigned		 n;

	(void) memset(obj, 0x0, sizeof(*obj));
	mj_create(obj, "array");
	obj->size = keyring->keyvsize;
	if (__ops_get_debug_level(__FILE__)) {
		(void) fprintf(io->errs, "__ops_keyring_json: vsize %u\n", obj->size);
	}
	if ((obj->value.v = calloc(sizeof(*obj->value.v), obj->size)) == NULL) {
		(void) fprintf(io->errs, "calloc failure\n");
		return 0;
	}
	for (n = 0, key = keyring->keys; n < keyring->keyc; ++n, ++key) {
		if (__ops_is_key_secret(key)) {
			__ops_sprint_mj(io, keyring, key, &obj->value.v[obj->c],
				"sec", &key->key.seckey.pubkey, psigs);
		} else {
			__ops_sprint_mj(io, keyring, key, &obj->value.v[obj->c],
				"signature ", &key->key.pubkey, psigs);
		}
		if (obj->value.v[obj->c].type != 0) {
			obj->c += 1;
		}
	}
	if (__ops_get_debug_level(__FILE__)) {
		char	*s;

		mj_asprint(&s, obj);
		(void) fprintf(stderr, "__ops_keyring_json: '%s'\n", s);
		free(s);
	}
	return 1;
}
示例#10
0
/**
\ingroup Core_Crypto
\brief Decrypts RSA-encrypted data
\param out Where to write the plaintext
\param in Encrypted data
\param length Length of encrypted data
\param seckey RSA secret key
\param pubkey RSA public key
\return size of recovered plaintext
*/
int 
__ops_rsa_private_decrypt(uint8_t *out,
			const uint8_t *in,
			size_t length,
			const __ops_rsa_seckey_t *seckey,
			const __ops_rsa_pubkey_t *pubkey)
{
	RSA            *keypair;
	int             n;
	char            errbuf[1024];

	keypair = RSA_new();
	keypair->n = pubkey->n;	/* XXX: do we need n? */
	keypair->d = seckey->d;
	keypair->p = seckey->q;
	keypair->q = seckey->p;

	/* debug */
	keypair->e = pubkey->e;
	if (RSA_check_key(keypair) != 1) {
		(void) fprintf(stderr, "RSA_check_key is not set\n");
		return 0;
	}
	/* end debug */

	n = RSA_private_decrypt((int)length, in, out, keypair, RSA_NO_PADDING);

	if (__ops_get_debug_level(__FILE__)) {
		printf("__ops_rsa_private_decrypt: n=%d\n",n);
	}

	errbuf[0] = '\0';
	if (n == -1) {
		unsigned long   err = ERR_get_error();

		ERR_error_string(err, &errbuf[0]);
		(void) fprintf(stderr, "openssl error : %s\n", errbuf);
	}
	keypair->n = keypair->d = keypair->p = keypair->q = NULL;
	RSA_free(keypair);

	return n;
}
示例#11
0
/**
 \ingroup HighLevel_KeyGenerate
 \brief Generates an RSA keypair
 \param numbits Modulus size
 \param e Public Exponent
 \param keydata Pointer to keydata struct to hold new key
 \return 1 if key generated successfully; otherwise 0
 \note It is the caller's responsibility to call __ops_keydata_free(keydata)
*/
static unsigned 
rsa_generate_keypair(__ops_key_t *keydata,
			const int numbits,
			const unsigned long e,
			const char *hashalg,
			const char *cipher)
{
	__ops_seckey_t *seckey;
	RSA            *rsa;
	BN_CTX         *ctx;
	__ops_output_t *output;
	__ops_memory_t   *mem;

	ctx = BN_CTX_new();
	__ops_keydata_init(keydata, OPS_PTAG_CT_SECRET_KEY);
	seckey = __ops_get_writable_seckey(keydata);

	/* generate the key pair */

	rsa = RSA_generate_key(numbits, e, NULL, NULL);

	/* populate __ops key from ssl key */

	seckey->pubkey.version = OPS_V4;
	seckey->pubkey.birthtime = time(NULL);
	seckey->pubkey.days_valid = 0;
	seckey->pubkey.alg = OPS_PKA_RSA;

	seckey->pubkey.key.rsa.n = BN_dup(rsa->n);
	seckey->pubkey.key.rsa.e = BN_dup(rsa->e);

	seckey->s2k_usage = OPS_S2KU_ENCRYPTED_AND_HASHED;
	seckey->s2k_specifier = OPS_S2KS_SALTED;
	/* seckey->s2k_specifier=OPS_S2KS_SIMPLE; */
	if ((seckey->hash_alg = __ops_str_to_hash_alg(hashalg)) == OPS_HASH_UNKNOWN) {
		seckey->hash_alg = OPS_HASH_SHA1;
	}
	seckey->alg = __ops_str_to_cipher(cipher);
	seckey->octetc = 0;
	seckey->checksum = 0;

	seckey->key.rsa.d = BN_dup(rsa->d);
	seckey->key.rsa.p = BN_dup(rsa->p);
	seckey->key.rsa.q = BN_dup(rsa->q);
	seckey->key.rsa.u = BN_mod_inverse(NULL, rsa->p, rsa->q, ctx);
	if (seckey->key.rsa.u == NULL) {
		(void) fprintf(stderr, "seckey->key.rsa.u is NULL\n");
		return 0;
	}
	BN_CTX_free(ctx);

	RSA_free(rsa);

	__ops_keyid(keydata->sigid, OPS_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
	__ops_fingerprint(&keydata->sigfingerprint, &keydata->key.seckey.pubkey, seckey->hash_alg);

	/* Generate checksum */

	output = NULL;
	mem = NULL;

	__ops_setup_memory_write(&output, &mem, 128);

	__ops_push_checksum_writer(output, seckey);

	switch (seckey->pubkey.alg) {
	case OPS_PKA_DSA:
		return __ops_write_mpi(output, seckey->key.dsa.x);
	case OPS_PKA_RSA:
	case OPS_PKA_RSA_ENCRYPT_ONLY:
	case OPS_PKA_RSA_SIGN_ONLY:
		if (!__ops_write_mpi(output, seckey->key.rsa.d) ||
		    !__ops_write_mpi(output, seckey->key.rsa.p) ||
		    !__ops_write_mpi(output, seckey->key.rsa.q) ||
		    !__ops_write_mpi(output, seckey->key.rsa.u)) {
			return 0;
		}
		break;
	case OPS_PKA_ELGAMAL:
		return __ops_write_mpi(output, seckey->key.elgamal.x);

	default:
		(void) fprintf(stderr, "Bad seckey->pubkey.alg\n");
		return 0;
	}

	/* close rather than pop, since its the only one on the stack */
	__ops_writer_close(output);
	__ops_teardown_memory_write(output, mem);

	/* should now have checksum in seckey struct */

	/* test */
	if (__ops_get_debug_level(__FILE__)) {
		test_seckey(seckey);
	}

	return 1;
}
示例#12
0
/* format a JSON object */
static void
format_json_key(FILE *fp, mj_t *obj, const int psigs)
{
	int64_t	 birthtime;
	int64_t	 duration;
	time_t	 now;
	char	 tbuf[32];
	char	*s;
	mj_t	*sub;
	int	 i;

	if (__ops_get_debug_level(__FILE__)) {
		mj_asprint(&s, obj);
		(void) fprintf(stderr, "formatobj: json is '%s'\n", s);
		free(s);
	}
	if (obj->c == 2 && obj->value.v[1].type == MJ_STRING &&
	    strcmp(obj->value.v[1].value.s, "[REVOKED]") == 0) {
		/* whole key has been rovoked - just return */
		return;
	}
	pobj(fp, &obj->value.v[mj_object_find(obj, "header", 0, 2) + 1], 0);
	p(fp, " ", NULL);
	pobj(fp, &obj->value.v[mj_object_find(obj, "key bits", 0, 2) + 1], 0);
	p(fp, "/", NULL);
	pobj(fp, &obj->value.v[mj_object_find(obj, "pka", 0, 2) + 1], 0);
	p(fp, " ", NULL);
	pobj(fp, &obj->value.v[mj_object_find(obj, "key id", 0, 2) + 1], 0);
	birthtime = strtoll(obj->value.v[mj_object_find(obj, "birthtime", 0, 2) + 1].value.s, NULL, 10);
	p(fp, " ", ptimestr(tbuf, sizeof(tbuf), birthtime), NULL);
	duration = strtoll(obj->value.v[mj_object_find(obj, "duration", 0, 2) + 1].value.s, NULL, 10);
	if (duration > 0) {
		now = time(NULL);
		p(fp, " ", (birthtime + duration < now) ? "[EXPIRED " : "[EXPIRES ",
			ptimestr(tbuf, sizeof(tbuf), birthtime + duration), "]", NULL);
	}
	p(fp, "\n", "Key fingerprint: ", NULL);
	pobj(fp, &obj->value.v[mj_object_find(obj, "fingerprint", 0, 2) + 1], 0);
	p(fp, "\n", NULL);
	/* go to field after \"duration\" */
	for (i = mj_object_find(obj, "duration", 0, 2) + 2; i < mj_arraycount(obj) ; i += 2) {
		if (strcmp(obj->value.v[i].value.s, "uid") == 0) {
			sub = &obj->value.v[i + 1];
			p(fp, "uid", NULL);
			pobj(fp, &sub->value.v[0], (psigs) ? 4 : 14); /* human name */
			pobj(fp, &sub->value.v[1], 1); /* any revocation */
			p(fp, "\n", NULL);
		} else if (strcmp(obj->value.v[i].value.s, "encryption") == 0) {
			sub = &obj->value.v[i + 1];
			p(fp, "encryption", NULL);
			pobj(fp, &sub->value.v[0], 1);	/* size */
			p(fp, "/", NULL);
			pobj(fp, &sub->value.v[1], 0); /* alg */
			p(fp, " ", NULL);
			pobj(fp, &sub->value.v[2], 0); /* id */
			p(fp, " ", ptimestr(tbuf, sizeof(tbuf), strtoll(sub->value.v[3].value.s, NULL, 10)),
				"\n", NULL);
		} else if (strcmp(obj->value.v[i].value.s, "sig") == 0) {
			sub = &obj->value.v[i + 1];
			p(fp, "sig", NULL);
			pobj(fp, &sub->value.v[0], 8);	/* size */
			p(fp, "  ", ptimestr(tbuf, sizeof(tbuf), strtoll(sub->value.v[1].value.s, NULL, 10)),
				" ", NULL); /* time */
			pobj(fp, &sub->value.v[2], 0); /* human name */
			p(fp, "\n", NULL);
		} else {
			fprintf(stderr, "weird '%s'\n", obj->value.v[i].value.s);
			pobj(fp, &obj->value.v[i], 0); /* human name */
		}
	}
	p(fp, "\n", NULL);
}