END_TEST /******************************************************************************* * unwrap */ START_TEST(test_asn1_unwrap) { chunk_t c0 = chunk_from_chars(0x30); chunk_t c1 = chunk_from_chars(0x30, 0x01, 0xaa); chunk_t c2 = chunk_from_chars(0x30, 0x80); chunk_t c3 = chunk_from_chars(0x30, 0x81); chunk_t c4 = chunk_from_chars(0x30, 0x81, 0x01, 0xaa); chunk_t c5 = chunk_from_chars(0x30, 0x81, 0x02, 0xaa); chunk_t inner; chunk_t inner_ref = chunk_from_chars(0xaa); ck_assert(asn1_unwrap(&c0, &inner) == ASN1_INVALID); ck_assert(asn1_unwrap(&c1, &inner) == ASN1_SEQUENCE); ck_assert(chunk_equals(inner, inner_ref)); ck_assert(asn1_unwrap(&c2, &inner) == ASN1_INVALID); ck_assert(asn1_unwrap(&c3, &inner) == ASN1_INVALID); ck_assert(asn1_unwrap(&c4, &inner) == ASN1_SEQUENCE); ck_assert(chunk_equals(inner, inner_ref)); ck_assert(asn1_unwrap(&c5, &inner) == ASN1_INVALID); }
/** * Encode the public key as Base64 encoded SSH key blob */ static bool build_public_key(chunk_t *encoding, va_list args) { bio_writer_t *writer; chunk_t n, e; if (cred_encoding_args(args, CRED_PART_RSA_MODULUS, &n, CRED_PART_RSA_PUB_EXP, &e, CRED_PART_END)) { writer = bio_writer_create(0); writer->write_data32(writer, chunk_from_str("ssh-rsa")); writer->write_data32(writer, e); writer->write_data32(writer, n); *encoding = chunk_to_base64(writer->get_buf(writer), NULL); writer->destroy(writer); return TRUE; } else if (cred_encoding_args(args, CRED_PART_EDDSA_PUB_ASN1_DER, &n, CRED_PART_END)) { chunk_t alg; char *prefix; int oid; /* parse subjectPublicKeyInfo */ if (asn1_unwrap(&n, &n) != ASN1_SEQUENCE) { return FALSE; } oid = asn1_parse_algorithmIdentifier(n, 1, NULL); switch (oid) { case OID_ED25519: prefix = "ssh-ed25519"; break; case OID_ED448: prefix = "ssh-ed448"; break; default: return FALSE; } if (asn1_unwrap(&n, &alg) != ASN1_SEQUENCE || asn1_unwrap(&n, &n) != ASN1_BIT_STRING || !n.len) { return FALSE; } writer = bio_writer_create(0); writer->write_data32(writer, chunk_from_str(prefix)); writer->write_data32(writer, chunk_skip(n, 1)); *encoding = chunk_to_base64(writer->get_buf(writer), NULL); writer->destroy(writer); return TRUE; } else if (cred_encoding_args(args, CRED_PART_ECDSA_PUB_ASN1_DER, &n, CRED_PART_END)) { chunk_t params, alg, q; int oid; /* parse subjectPublicKeyInfo */ if (asn1_unwrap(&n, &n) != ASN1_SEQUENCE) { return FALSE; } oid = asn1_parse_algorithmIdentifier(n, 1, ¶ms); if (oid != OID_EC_PUBLICKEY || asn1_unwrap(¶ms, ¶ms) != ASN1_OID) { return FALSE; } oid = asn1_known_oid(params); if (oid == OID_UNKNOWN) { return FALSE; } if (asn1_unwrap(&n, &alg) != ASN1_SEQUENCE || asn1_unwrap(&n, &q) != ASN1_BIT_STRING) { return FALSE; } writer = bio_writer_create(0); write_ec_identifier(writer, ECDSA_PREFIX, oid, params); write_ec_identifier(writer, "", oid, params); q = chunk_skip_zero(q); writer->write_data32(writer, q); *encoding = chunk_to_base64(writer->get_buf(writer), NULL); writer->destroy(writer); return TRUE; } return FALSE; }