Return to sshkey_encoder.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / sshkey |
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: }