Merge commit 'origin/silc.1.1.branch'
[silc.git] / lib / silccore / silcpubkey.c
1 /*
2
3   silcpubkey.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2005 - 2007 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 #include "silc.h"
21
22 /* Encodes Public Key Payload for transmitting public keys and certificates. */
23
24 SilcBuffer silc_public_key_payload_encode(SilcStack stack,
25                                           SilcPublicKey public_key)
26 {
27   SilcBuffer buffer;
28   unsigned char *pk;
29   SilcUInt32 pk_len;
30   SilcPKCSType type;
31
32   if (!public_key)
33     return NULL;
34
35   type = silc_pkcs_get_type(public_key);
36   pk = silc_pkcs_public_key_encode(stack, public_key, &pk_len);
37   if (!pk)
38     return NULL;
39
40   buffer = silc_buffer_salloc_size(stack, 4 + pk_len);
41   if (!buffer) {
42     silc_sfree(stack, pk);
43     return NULL;
44   }
45
46   if (silc_buffer_sformat(stack, buffer,
47                           SILC_STR_UI_SHORT(pk_len),
48                           SILC_STR_UI_SHORT(type),
49                           SILC_STR_DATA(pk, pk_len),
50                           SILC_STR_END) < 0) {
51     silc_buffer_sfree(stack, buffer);
52     silc_sfree(stack, pk);
53     return NULL;
54   }
55
56   silc_sfree(stack, pk);
57   return buffer;
58 }
59
60 /* Decodes public key payload and returns allocated public key */
61
62 SilcBool silc_public_key_payload_decode(unsigned char *data,
63                                         SilcUInt32 data_len,
64                                         SilcPublicKey *public_key)
65 {
66   SilcBufferStruct buf;
67   SilcUInt16 pk_len, pk_type;
68   unsigned char *pk;
69   int ret;
70
71   if (!public_key)
72     return FALSE;
73
74   silc_buffer_set(&buf, data, data_len);
75   ret = silc_buffer_unformat(&buf,
76                              SILC_STR_ADVANCE,
77                              SILC_STR_UI_SHORT(&pk_len),
78                              SILC_STR_UI_SHORT(&pk_type),
79                              SILC_STR_END);
80   if (ret < 0 || pk_len > data_len - 4)
81     return FALSE;
82
83   if (pk_type < SILC_PKCS_SILC || pk_type > SILC_PKCS_SPKI)
84     return FALSE;
85
86   ret = silc_buffer_unformat(&buf,
87                              SILC_STR_DATA(&pk, pk_len),
88                              SILC_STR_END);
89   if (ret < 0)
90     return FALSE;
91
92   return silc_pkcs_public_key_alloc((SilcPKCSType)pk_type,
93                                     pk, pk_len, public_key);
94 }