Annotation of embedaddon/strongswan/src/libstrongswan/plugins/sshkey/sshkey_encoder.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2013-2018 Tobias Brunner
! 3: * HSR Hochschule fuer Technik Rapperswil
! 4: *
! 5: * This program is free software; you can redistribute it and/or modify it
! 6: * under the terms of the GNU General Public License as published by the
! 7: * Free Software Foundation; either version 2 of the License, or (at your
! 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 9: *
! 10: * This program is distributed in the hope that it will be useful, but
! 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 13: * for more details.
! 14: */
! 15:
! 16: #include "sshkey_encoder.h"
! 17:
! 18: #include <asn1/asn1.h>
! 19: #include <asn1/oid.h>
! 20: #include <bio/bio_writer.h>
! 21:
! 22: #define ECDSA_PREFIX "ecdsa-sha2-"
! 23:
! 24: /**
! 25: * Write an EC domain parameter identifier as defined in RFC 5656
! 26: */
! 27: static void write_ec_identifier(bio_writer_t *writer, char *prefix, int oid,
! 28: chunk_t enc)
! 29: {
! 30: char *curve, identifier[128];
! 31:
! 32: switch (oid)
! 33: {
! 34: case OID_PRIME256V1:
! 35: curve = strdup("nistp256");
! 36: break;
! 37: case OID_SECT384R1:
! 38: curve = strdup("nistp384");
! 39: break;
! 40: case OID_SECT521R1:
! 41: curve = strdup("nistp521");
! 42: break;
! 43: default:
! 44: curve = asn1_oid_to_string(enc);
! 45: break;
! 46: }
! 47: if (curve && snprintf(identifier, sizeof(identifier), "%s%s", prefix,
! 48: curve) < sizeof(identifier))
! 49: {
! 50: writer->write_data32(writer, chunk_from_str(identifier));
! 51: }
! 52: free(curve);
! 53: }
! 54:
! 55: /**
! 56: * Encode the public key as Base64 encoded SSH key blob
! 57: */
! 58: static bool build_public_key(chunk_t *encoding, va_list args)
! 59: {
! 60: bio_writer_t *writer;
! 61: chunk_t n, e;
! 62:
! 63: if (cred_encoding_args(args, CRED_PART_RSA_MODULUS, &n,
! 64: CRED_PART_RSA_PUB_EXP, &e, CRED_PART_END))
! 65: {
! 66: writer = bio_writer_create(0);
! 67: writer->write_data32(writer, chunk_from_str("ssh-rsa"));
! 68:
! 69: writer->write_data32(writer, e);
! 70: writer->write_data32(writer, n);
! 71: *encoding = chunk_to_base64(writer->get_buf(writer), NULL);
! 72: writer->destroy(writer);
! 73: return TRUE;
! 74: }
! 75: else if (cred_encoding_args(args, CRED_PART_EDDSA_PUB_ASN1_DER, &n,
! 76: CRED_PART_END))
! 77: {
! 78: chunk_t alg;
! 79: char *prefix;
! 80: int oid;
! 81:
! 82: /* parse subjectPublicKeyInfo */
! 83: if (asn1_unwrap(&n, &n) != ASN1_SEQUENCE)
! 84: {
! 85: return FALSE;
! 86: }
! 87: oid = asn1_parse_algorithmIdentifier(n, 1, NULL);
! 88: switch (oid)
! 89: {
! 90: case OID_ED25519:
! 91: prefix = "ssh-ed25519";
! 92: break;
! 93: case OID_ED448:
! 94: prefix = "ssh-ed448";
! 95: break;
! 96: default:
! 97: return FALSE;
! 98: }
! 99: if (asn1_unwrap(&n, &alg) != ASN1_SEQUENCE ||
! 100: asn1_unwrap(&n, &n) != ASN1_BIT_STRING || !n.len)
! 101: {
! 102: return FALSE;
! 103: }
! 104: writer = bio_writer_create(0);
! 105: writer->write_data32(writer, chunk_from_str(prefix));
! 106: writer->write_data32(writer, chunk_skip(n, 1));
! 107: *encoding = chunk_to_base64(writer->get_buf(writer), NULL);
! 108: writer->destroy(writer);
! 109: return TRUE;
! 110: }
! 111: else if (cred_encoding_args(args, CRED_PART_ECDSA_PUB_ASN1_DER, &n,
! 112: CRED_PART_END))
! 113: {
! 114: chunk_t params, alg, q;
! 115: int oid;
! 116:
! 117: /* parse subjectPublicKeyInfo */
! 118: if (asn1_unwrap(&n, &n) != ASN1_SEQUENCE)
! 119: {
! 120: return FALSE;
! 121: }
! 122: oid = asn1_parse_algorithmIdentifier(n, 1, ¶ms);
! 123: if (oid != OID_EC_PUBLICKEY ||
! 124: asn1_unwrap(¶ms, ¶ms) != ASN1_OID)
! 125: {
! 126: return FALSE;
! 127: }
! 128: oid = asn1_known_oid(params);
! 129: if (oid == OID_UNKNOWN)
! 130: {
! 131: return FALSE;
! 132: }
! 133: if (asn1_unwrap(&n, &alg) != ASN1_SEQUENCE ||
! 134: asn1_unwrap(&n, &q) != ASN1_BIT_STRING)
! 135: {
! 136: return FALSE;
! 137: }
! 138: writer = bio_writer_create(0);
! 139: write_ec_identifier(writer, ECDSA_PREFIX, oid, params);
! 140: write_ec_identifier(writer, "", oid, params);
! 141:
! 142: q = chunk_skip_zero(q);
! 143: writer->write_data32(writer, q);
! 144: *encoding = chunk_to_base64(writer->get_buf(writer), NULL);
! 145: writer->destroy(writer);
! 146: return TRUE;
! 147: }
! 148: return FALSE;
! 149: }
! 150:
! 151: bool sshkey_encoder_encode(cred_encoding_type_t type, chunk_t *encoding,
! 152: va_list args)
! 153: {
! 154: switch (type)
! 155: {
! 156: case PUBKEY_SSHKEY:
! 157: return build_public_key(encoding, args);
! 158: default:
! 159: return FALSE;
! 160: }
! 161: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>