Bug fix for multi-stanza key use and replay attack detection
[fwknop.git] / lib / fko_digest.c
1 /*
2  *****************************************************************************
3  *
4  * File:    fko_digest.c
5  *
6  * Author:  Damien S. Stuart
7  *
8  * Purpose: Create the base64-encoded digest for the current spa data. The
9  *          digest used is determined by the digest_type setting in the
10  *          fko context.
11  *
12  * Copyright 2009-2010 Damien Stuart (dstuart@dstuart.org)
13  *
14  *  License (GNU Public License):
15  *
16  *  This program is free software; you can redistribute it and/or
17  *  modify it under the terms of the GNU General Public License
18  *  as published by the Free Software Foundation; either version 2
19  *  of the License, or (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, write to the Free Software
28  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
29  *  USA
30  *
31  *****************************************************************************
32 */
33 #include "fko_common.h"
34 #include "fko.h"
35 #include "digest.h"
36
37 /* Set the SPA digest type.
38 */
39 static int
40 set_spa_digest_type(fko_ctx_t ctx,
41     short *digest_type_field, const short digest_type)
42 {
43     /* Must be initialized
44     */
45     if(!CTX_INITIALIZED(ctx))
46         return(FKO_ERROR_CTX_NOT_INITIALIZED);
47
48     if(digest_type < 1 || digest_type >= FKO_LAST_DIGEST_TYPE)
49         return(FKO_ERROR_INVALID_DATA);
50
51     *digest_type_field = digest_type;
52
53     ctx->state |= FKO_DIGEST_TYPE_MODIFIED;
54
55     return(FKO_SUCCESS);
56 }
57
58 int
59 fko_set_spa_digest_type(fko_ctx_t ctx, const short digest_type)
60 {
61     return set_spa_digest_type(ctx, &ctx->digest_type, digest_type);
62 }
63
64 int
65 fko_set_raw_spa_digest_type(fko_ctx_t ctx, const short raw_digest_type)
66 {
67     return set_spa_digest_type(ctx, &ctx->raw_digest_type, raw_digest_type);
68 }
69
70 /* Return the SPA digest type.
71 */
72 int
73 fko_get_spa_digest_type(fko_ctx_t ctx, short *digest_type)
74 {
75     /* Must be initialized
76     */
77     if(!CTX_INITIALIZED(ctx))
78         return(FKO_ERROR_CTX_NOT_INITIALIZED);
79
80     *digest_type = ctx->digest_type;
81
82     return(FKO_SUCCESS);
83 }
84
85 /* Return the SPA digest type.
86 */
87 int
88 fko_get_raw_spa_digest_type(fko_ctx_t ctx, short *raw_digest_type)
89 {
90     /* Must be initialized
91     */
92     if(!CTX_INITIALIZED(ctx))
93         return(FKO_ERROR_CTX_NOT_INITIALIZED);
94
95     *raw_digest_type = ctx->raw_digest_type;
96
97     return(FKO_SUCCESS);
98 }
99
100 static int
101 set_digest(char *data, char **digest, short digest_type)
102 {
103     char    *md = NULL;
104
105     switch(digest_type)
106     {
107         case FKO_DIGEST_MD5:
108             md = malloc(MD_HEX_SIZE(MD5_DIGEST_LENGTH)+1);
109             if(md == NULL)
110                 return(FKO_ERROR_MEMORY_ALLOCATION);
111
112             md5_base64(md,
113                 (unsigned char*)data, strlen(data));
114             break;
115
116         case FKO_DIGEST_SHA1:
117             md = malloc(MD_HEX_SIZE(SHA1_DIGEST_LENGTH)+1);
118             if(md == NULL)
119                 return(FKO_ERROR_MEMORY_ALLOCATION);
120
121             sha1_base64(md,
122                 (unsigned char*)data, strlen(data));
123             break;
124
125         case FKO_DIGEST_SHA256:
126             md = malloc(MD_HEX_SIZE(SHA256_DIGEST_LENGTH)+1);
127             if(md == NULL)
128                 return(FKO_ERROR_MEMORY_ALLOCATION);
129
130             sha256_base64(md,
131                 (unsigned char*)data, strlen(data));
132             break;
133
134         case FKO_DIGEST_SHA384:
135             md = malloc(MD_HEX_SIZE(SHA384_DIGEST_LENGTH)+1);
136             if(md == NULL)
137                 return(FKO_ERROR_MEMORY_ALLOCATION);
138
139             sha384_base64(md,
140                 (unsigned char*)data, strlen(data));
141             break;
142
143         case FKO_DIGEST_SHA512:
144             md = malloc(MD_HEX_SIZE(SHA512_DIGEST_LENGTH)+1);
145             if(md == NULL)
146                 return(FKO_ERROR_MEMORY_ALLOCATION);
147
148             sha512_base64(md,
149                 (unsigned char*)data, strlen(data));
150             break;
151
152         default:
153             return(FKO_ERROR_INVALID_DIGEST_TYPE);
154     }
155
156     /* Just in case this is a subsquent call to this function.  We
157      * do not want to be leaking memory.
158     */
159     if(*digest != NULL)
160         free(*digest);
161
162     *digest = md;
163
164     return(FKO_SUCCESS);
165 }
166
167 int
168 fko_set_spa_digest(fko_ctx_t ctx)
169 {
170     /* Must be initialized
171     */
172     if(!CTX_INITIALIZED(ctx))
173         return(FKO_ERROR_CTX_NOT_INITIALIZED);
174
175     /* Must have encoded message data to start with.
176     */
177     if(ctx->encoded_msg == NULL)
178         return(FKO_ERROR_MISSING_ENCODED_DATA);
179
180     return set_digest(ctx->encoded_msg,
181         &ctx->digest, ctx->digest_type);
182 }
183
184 int
185 fko_set_raw_spa_digest(fko_ctx_t ctx)
186 {
187     /* Must be initialized
188     */
189     if(!CTX_INITIALIZED(ctx))
190         return(FKO_ERROR_CTX_NOT_INITIALIZED);
191
192     /* Must have encoded message data to start with.
193     */
194     if(ctx->encrypted_msg == NULL)
195         return(FKO_ERROR_MISSING_ENCODED_DATA);
196
197     return set_digest(ctx->encrypted_msg,
198         &ctx->raw_digest, ctx->raw_digest_type);
199 }
200
201 int
202 fko_get_spa_digest(fko_ctx_t ctx, char **md)
203 {
204     /* Must be initialized
205     */
206     if(!CTX_INITIALIZED(ctx))
207         return(FKO_ERROR_CTX_NOT_INITIALIZED);
208
209     *md = ctx->digest;
210
211     return(FKO_SUCCESS);
212 }
213
214 int
215 fko_get_raw_spa_digest(fko_ctx_t ctx, char **md)
216 {
217     /* Must be initialized
218     */
219     if(!CTX_INITIALIZED(ctx))
220         return(FKO_ERROR_CTX_NOT_INITIALIZED);
221
222     *md = ctx->raw_digest;
223
224     return(FKO_SUCCESS);
225 }
226
227 /***EOF***/