Esempio n. 1
0
END_TEST

/*******************************************************************************
 * bitstring
 */

START_TEST(test_asn1_bitstring)
{
	chunk_t a = chunk_empty;
	chunk_t b = chunk_from_chars(0x03, 0x05, 0x00, 0xa1, 0xa2, 0xa3, 0xa4);
	chunk_t c = chunk_from_chars(0xa1, 0xa2, 0xa3, 0xa4);
	chunk_t d = chunk_clone(c);

	a = asn1_bitstring("c", c);
	ck_assert(chunk_equals(a, b));
	chunk_free(&a);

	a = asn1_bitstring("m", d);
	ck_assert(chunk_equals(a, b));
	chunk_free(&a);
}
Esempio n. 2
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, PUBKEY_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);
	if (!hasher || !hasher->get_hash(hasher, keyInfo, digest.ptr))
	{
		memset(digest.ptr, 0, digest.len);
	}
	DESTROY_IF(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 = chunk_to_hex(digest, NULL, TRUE);
}
Esempio n. 3
0
/**
 * Load a generic public key from an SSH key blob
 */
static sshkey_public_key_t *parse_public_key(chunk_t blob)
{
	bio_reader_t *reader;
	chunk_t format;

	reader = bio_reader_create(blob);
	if (!reader->read_data32(reader, &format))
	{
		DBG1(DBG_LIB, "invalid key format in SSH key");
		reader->destroy(reader);
		return NULL;
	}
	if (chunk_equals(format, chunk_from_str("ssh-rsa")))
	{
		chunk_t n, e;

		if (!reader->read_data32(reader, &e) ||
			!reader->read_data32(reader, &n))
		{
			DBG1(DBG_LIB, "invalid RSA key in SSH key");
			reader->destroy(reader);
			return NULL;
		}
		reader->destroy(reader);
		return lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
						BUILD_RSA_MODULUS, n, BUILD_RSA_PUB_EXP, e, BUILD_END);
	}
	else if (format.len > strlen(ECDSA_PREFIX) &&
			 strneq(format.ptr, ECDSA_PREFIX, strlen(ECDSA_PREFIX)))
	{
		chunk_t ec_blob, identifier, q, oid, encoded;
		sshkey_public_key_t *key;

		ec_blob = reader->peek(reader);
		reader->destroy(reader);
		reader = bio_reader_create(ec_blob);
		if (!reader->read_data32(reader, &identifier) ||
			!reader->read_data32(reader, &q))
		{
			DBG1(DBG_LIB, "invalid ECDSA key in SSH key");
			reader->destroy(reader);
			return NULL;
		}
		oid = parse_ec_identifier(identifier);
		if (!oid.ptr)
		{
			DBG1(DBG_LIB, "invalid ECDSA key identifier in SSH key");
			reader->destroy(reader);
			return NULL;
		}
		reader->destroy(reader);
		/* build key from subjectPublicKeyInfo */
		encoded = asn1_wrap(ASN1_SEQUENCE, "mm",
						asn1_wrap(ASN1_SEQUENCE, "mm",
							asn1_build_known_oid(OID_EC_PUBLICKEY), oid),
						asn1_bitstring("c", q));
		key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
							KEY_ECDSA, BUILD_BLOB_ASN1_DER, encoded, BUILD_END);
		chunk_free(&encoded);
		return key;
	}
	DBG1(DBG_LIB, "unsupported SSH key format %.*s", (int)format.len,
		 format.ptr);
	reader->destroy(reader);
	return NULL;
}