e0bbce0fff3a8bf8d301e25ef26388079271b39a
[silc.git] / lib / silcske / groups.c
1 /*
2
3   groups.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2000 - 2001 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; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /* $Id$ */
21
22 #include "silcincludes.h"
23 #include "groups_internal.h"
24
25 /* Fixed and public Diffie Hellman Groups defined by the SKE
26    protocol. These are equivalent to the OAKLEY Key Determination
27    protocol groups (taken from RFC 2412). */
28 const struct SilcSKEDiffieHellmanGroupDefStruct silc_ske_groups[] = 
29 {
30   /* 1024 bits modulus (Mandatory group) */
31   { 1, "diffie-hellman-group1",
32
33     "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
34     "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
35     "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
36     "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
37     "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
38     "FFFFFFFFFFFFFFFF",
39
40     "7FFFFFFFFFFFFFFFE487ED5110B4611A62633145C06E0E68"
41     "948127044533E63A0105DF531D89CD9128A5043CC71A026E"
42     "F7CA8CD9E69D218D98158536F92F8A1BA7F09AB6B6A8E122"
43     "F242DABB312F3F637A262174D31BF6B585FFAE5B7A035BF6"
44     "F71C35FDAD44CFD2D74F9208BE258FF324943328F67329C0"
45     "FFFFFFFFFFFFFFFF",
46     "2" },
47
48   /* 1536 bits modulus (Optional group) */
49   { 2, "diffie-hellman-group2",
50
51     "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
52     "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
53     "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
54     "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
55     "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
56     "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
57     "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
58     "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF",
59
60     "7FFFFFFFFFFFFFFFE487ED5110B4611A62633145C06E0E68"
61     "948127044533E63A0105DF531D89CD9128A5043CC71A026E"
62     "F7CA8CD9E69D218D98158536F92F8A1BA7F09AB6B6A8E122"
63     "F242DABB312F3F637A262174D31BF6B585FFAE5B7A035BF6"
64     "F71C35FDAD44CFD2D74F9208BE258FF324943328F6722D9E"
65     "E1003E5C50B1DF82CC6D241B0E2AE9CD348B1FD47E9267AF"
66     "C1B2AE91EE51D6CB0E3179AB1042A95DCF6A9483B84B4B36"
67     "B3861AA7255E4C0278BA36046511B993FFFFFFFFFFFFFFFF",
68     "2" },
69
70   { 0, NULL, NULL, NULL }
71 };
72
73 /* Returns Diffie Hellman group by group number */
74
75 SilcSKEStatus silc_ske_group_get_by_number(int number,
76                                            SilcSKEDiffieHellmanGroup *ret)
77 {
78   int i;
79   SilcSKEDiffieHellmanGroup group;
80
81   for (i = 0; silc_ske_groups[i].name; i++) {
82     if (silc_ske_groups[i].number == number)
83       break;
84   }
85
86   if (silc_ske_groups[i].name == NULL) {
87     SILC_LOG_ERROR(("Unsupported Diffie-Hellman group number %d", number));
88     return SILC_SKE_STATUS_UNKNOWN_GROUP;
89   }
90
91   /* Return the group */
92   if (ret) {
93     group = silc_calloc(1, sizeof(*group));
94     group->number = number;
95     group->name = silc_ske_groups[i].name;
96     silc_mp_init(&group->group);
97     silc_mp_init(&group->group_order);
98     silc_mp_init(&group->generator);
99     silc_mp_set_str(&group->group, silc_ske_groups[i].group, 16);
100     silc_mp_set_str(&group->group_order, silc_ske_groups[i].group_order, 16);
101     silc_mp_set_str(&group->generator, silc_ske_groups[i].generator, 16);
102     
103     *ret = group;
104   }
105
106   return SILC_SKE_STATUS_OK;
107 }
108
109 /* Returns Diffie Hellman group by name */
110
111 SilcSKEStatus silc_ske_group_get_by_name(const char *name,
112                                          SilcSKEDiffieHellmanGroup *ret)
113 {
114   int i;
115   SilcSKEDiffieHellmanGroup group;
116
117   for (i = 0; silc_ske_groups[i].name; i++) {
118     if (!strcmp(silc_ske_groups[i].name, name))
119       break;
120   }
121
122   if (silc_ske_groups[i].name == NULL) {
123     SILC_LOG_ERROR(("Unsupported Diffie-Hellman group `%s'", name));
124     return SILC_SKE_STATUS_UNKNOWN_GROUP;
125   }
126
127   /* Return the group */
128   if (ret) {
129     group = silc_calloc(1, sizeof(*group));
130     group->number = silc_ske_groups[i].number;
131     group->name = silc_ske_groups[i].name;
132     silc_mp_init(&group->group);
133     silc_mp_init(&group->group_order);
134     silc_mp_init(&group->generator);
135     silc_mp_set_str(&group->group, silc_ske_groups[i].group, 16);
136     silc_mp_set_str(&group->group_order, silc_ske_groups[i].group_order, 16);
137     silc_mp_set_str(&group->generator, silc_ske_groups[i].generator, 16);
138     
139     *ret = group;
140   }
141
142   return SILC_SKE_STATUS_OK;
143 }
144
145 /* Free group */
146
147 void silc_ske_group_free(SilcSKEDiffieHellmanGroup group)
148 {
149   silc_mp_uninit(&group->group);
150   silc_mp_uninit(&group->group_order);
151   silc_mp_uninit(&group->generator);
152   silc_free(group);
153 }
154
155 /* Returns comma separated list of supported groups */
156
157 char *silc_ske_get_supported_groups()
158 {
159   char *list = NULL;
160   int i, len;
161
162   len = 0;
163   for (i = 0; silc_ske_groups[i].name; i++) {
164     len += strlen(silc_ske_groups[i].name);
165     list = silc_realloc(list, len + 1);
166
167     memcpy(list + (len - strlen(silc_ske_groups[i].name)), 
168            silc_ske_groups[i].name, strlen(silc_ske_groups[i].name));
169     memcpy(list + len, ",", 1);
170     len++;
171   }
172
173   list[len - 1] = 0;
174
175   return list;
176 }
177
178 /* Returns the number of the `group'. */
179
180 int silc_ske_group_get_number(SilcSKEDiffieHellmanGroup group)
181 {
182   return group->number;
183 }
184
185 /* Returns the name of the `group'. */
186
187 const char *silc_ske_group_get_name(SilcSKEDiffieHellmanGroup group)
188 {
189   return group->name;
190 }