Merge branch 'topic/mm-fixes' of git://208.110.73.182/silc into 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 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(SilcPublicKey public_key)
25 {
26   SilcBuffer buffer;
27   unsigned char *pk;
28   SilcUInt32 pk_len;
29   SilcPKCSType type;
30
31   if (!public_key)
32     return NULL;
33
34   type = silc_pkcs_get_type(public_key);
35   pk = silc_pkcs_public_key_encode(public_key, &pk_len);
36   if (!pk)
37     return NULL;
38
39   buffer = silc_buffer_alloc_size(4 + pk_len);
40   if (!buffer) {
41     silc_free(pk);
42     return NULL;
43   }
44
45   if (silc_buffer_format(buffer,
46                          SILC_STR_UI_SHORT(pk_len),
47                          SILC_STR_UI_SHORT(type),
48                          SILC_STR_DATA(pk, pk_len),
49                          SILC_STR_END) < 0) {
50     silc_buffer_free(buffer);
51     silc_free(pk);
52     return NULL;
53   }
54
55   silc_free(pk);
56   return buffer;
57 }
58
59 /* Decodes public key payload and returns allocated public key */
60
61 SilcBool silc_public_key_payload_decode(unsigned char *data,
62                                         SilcUInt32 data_len,
63                                         SilcPublicKey *public_key)
64 {
65   SilcBufferStruct buf;
66   SilcUInt16 pk_len, pk_type;
67   unsigned char *pk;
68   int ret;
69
70   if (!public_key)
71     return FALSE;
72
73   silc_buffer_set(&buf, data, data_len);
74   ret = silc_buffer_unformat(&buf,
75                              SILC_STR_ADVANCE,
76                              SILC_STR_UI_SHORT(&pk_len),
77                              SILC_STR_UI_SHORT(&pk_type),
78                              SILC_STR_END);
79   if (ret < 0 || pk_len > data_len - 4)
80     return FALSE;
81
82   if (pk_type < SILC_PKCS_SILC || pk_type > SILC_PKCS_SPKI)
83     return FALSE;
84
85   ret = silc_buffer_unformat(&buf,
86                              SILC_STR_DATA(&pk, pk_len),
87                              SILC_STR_END);
88   if (ret < 0)
89     return FALSE;
90
91   return silc_pkcs_public_key_alloc((SilcPKCSType)pk_type,
92                                     pk, pk_len, public_key);
93 }