updates.
[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     return SILC_SKE_STATUS_UNKNOWN_GROUP;
88
89   /* Return the group */
90   if (ret) {
91     group = silc_calloc(1, sizeof(*group));
92     group->number = number;
93     group->name = silc_ske_groups[i].name;
94     silc_mp_init(&group->group);
95     silc_mp_init(&group->group_order);
96     silc_mp_init(&group->generator);
97     silc_mp_set_str(&group->group, silc_ske_groups[i].group, 16);
98     silc_mp_set_str(&group->group_order, silc_ske_groups[i].group_order, 16);
99     silc_mp_set_str(&group->generator, silc_ske_groups[i].generator, 16);
100     
101     *ret = group;
102   }
103
104   return SILC_SKE_STATUS_OK;
105 }
106
107 /* Returns Diffie Hellman group by name */
108
109 SilcSKEStatus silc_ske_group_get_by_name(const char *name,
110                                          SilcSKEDiffieHellmanGroup *ret)
111 {
112   int i;
113   SilcSKEDiffieHellmanGroup group;
114
115   for (i = 0; silc_ske_groups[i].name; i++) {
116     if (!strcmp(silc_ske_groups[i].name, name))
117       break;
118   }
119
120   if (silc_ske_groups[i].name == NULL)
121     return SILC_SKE_STATUS_UNKNOWN_GROUP;
122
123   /* Return the group */
124   if (ret) {
125     group = silc_calloc(1, sizeof(*group));
126     group->number = silc_ske_groups[i].number;
127     group->name = silc_ske_groups[i].name;
128     silc_mp_init(&group->group);
129     silc_mp_init(&group->group_order);
130     silc_mp_init(&group->generator);
131     silc_mp_set_str(&group->group, silc_ske_groups[i].group, 16);
132     silc_mp_set_str(&group->group_order, silc_ske_groups[i].group_order, 16);
133     silc_mp_set_str(&group->generator, silc_ske_groups[i].generator, 16);
134     
135     *ret = group;
136   }
137
138   return SILC_SKE_STATUS_OK;
139 }
140
141 /* Free group */
142
143 void silc_ske_group_free(SilcSKEDiffieHellmanGroup group)
144 {
145   silc_mp_uninit(&group->group);
146   silc_mp_uninit(&group->group_order);
147   silc_mp_uninit(&group->generator);
148   silc_free(group);
149 }
150
151 /* Returns comma separated list of supported groups */
152
153 char *silc_ske_get_supported_groups()
154 {
155   char *list = NULL;
156   int i, len;
157
158   len = 0;
159   for (i = 0; silc_ske_groups[i].name; i++) {
160     len += strlen(silc_ske_groups[i].name);
161     list = silc_realloc(list, len + 1);
162
163     memcpy(list + (len - strlen(silc_ske_groups[i].name)), 
164            silc_ske_groups[i].name, strlen(silc_ske_groups[i].name));
165     memcpy(list + len, ",", 1);
166     len++;
167   }
168
169   list[len - 1] = 0;
170
171   return list;
172 }
173
174 /* Returns the number of the `group'. */
175
176 int silc_ske_group_get_number(SilcSKEDiffieHellmanGroup group)
177 {
178   return group->number;
179 }
180
181 /* Returns the name of the `group'. */
182
183 const char *silc_ske_group_get_name(SilcSKEDiffieHellmanGroup group)
184 {
185   return group->name;
186 }