]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libstrongswan/plugins/dnskey/dnskey_encoder.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / libstrongswan / plugins / dnskey / dnskey_encoder.c
1 /*
2 * Copyright (C) 2013 Andreas Steffen
3 *
4 * Copyright (C) secunet Security Networks AG
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "dnskey_encoder.h"
18
19 #include <utils/debug.h>
20
21 /**
22 * Encode an RSA public key in DNSKEY format (RFC 3110)
23 */
24 static bool build_pub(chunk_t *encoding, va_list args)
25 {
26 chunk_t n, e, pubkey;
27 size_t exp_len;
28 u_char *pos;
29
30 if (cred_encoding_args(args, CRED_PART_RSA_MODULUS, &n,
31 CRED_PART_RSA_PUB_EXP, &e, CRED_PART_END))
32 {
33 /* remove leading zeros in exponent and modulus */
34 while (*e.ptr == 0)
35 {
36 e = chunk_skip(e, 1);
37 }
38 while (*n.ptr == 0)
39 {
40 n = chunk_skip(n, 1);
41 }
42
43 if (e.len < 256)
44 {
45 /* exponent length fits into a single octet */
46 exp_len = 1;
47 pubkey = chunk_alloc(exp_len + e.len + n.len);
48 pubkey.ptr[0] = (char)e.len;
49 }
50 else if (e.len < 65536)
51 {
52 /* exponent length fits into two octets preceded by zero octet */
53 exp_len = 3;
54 pubkey = chunk_alloc(exp_len + e.len + n.len);
55 pubkey.ptr[0] = 0x00;
56 htoun16(pubkey.ptr + 1, e.len);
57 }
58 else
59 {
60 /* exponent length is too large */
61 return FALSE;
62 }
63
64 /* copy exponent and modulus and convert to base64 format */
65 pos = pubkey.ptr + exp_len;
66 memcpy(pos, e.ptr, e.len);
67 pos += e.len;
68 memcpy(pos, n.ptr, n.len);
69 *encoding = chunk_to_base64(pubkey, NULL);
70 chunk_free(&pubkey);
71
72 return TRUE;
73 }
74 return FALSE;
75 }
76
77 /**
78 * See header.
79 */
80 bool dnskey_encoder_encode(cred_encoding_type_t type, chunk_t *encoding,
81 va_list args)
82 {
83 switch (type)
84 {
85 case PUBKEY_DNSKEY:
86 return build_pub(encoding, args);
87 default:
88 return FALSE;
89 }
90 }
91
92