*** empty log message ***
[gnutls.git] / libextra / opencdk / trustdb.c
blob36d89e7a568d5def9c31c8ae79d2c4eca165c4f9
1 /* -*- Mode: C; c-file-style: "bsd" -*- */
2 /* trustdb.c - High level interface for ownertrust handling
3 * Copyright (C) 2001, 2002, 2003 Timo Schulz
5 * This file is part of OpenCDK.
7 * OpenCDK is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * OpenCDK is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with OpenCDK; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25 #include <stdio.h>
27 #include "opencdk.h"
28 #include "main.h"
30 #define TRUST_MASK 15
31 #define RECORD_SIZE 40
32 #define MIN_TRUSTDB_VER 3
35 enum {
36 TDB_RECORD_TRUST = 12,
37 TDB_RECORD_VALID = 13,
40 struct tdb_record_s {
41 int recno;
42 union {
43 struct {
44 byte reserved;
45 byte fpr[20];
46 int ownertrust;
47 byte depth;
48 u32 validlist;
49 } trust;
50 struct {
51 byte reserved;
52 byte fpr[20];
53 u32 next;
54 int valid;
55 } valid;
56 } u;
58 typedef struct tdb_record_s *tdb_record_t;
61 static void
62 trustdb_rec_release( tdb_record_t rec )
64 if( rec ) {
65 rec->recno = 0;
66 cdk_free( rec );
71 static tdb_record_t
72 trustdb_rec_new( void )
74 tdb_record_t rec;
76 rec = cdk_calloc( 1, sizeof *rec );
77 if( !rec )
78 return NULL;
79 return rec;
83 static int
84 trustdb_check( cdk_stream_t a, int req_ver )
86 int rc = 0;
87 int c = 0, nread;
88 byte magic[3];
90 cdk_stream_seek( a, 0 );
91 c = cdk_stream_getc( a );
92 if( c == EOF || c != 1 )
93 return CDK_General_Error;
94 nread = cdk_stream_read( a, magic, 3 );
95 if( nread == EOF )
96 return CDK_File_Error;
97 c = cdk_stream_getc( a );
98 if( c == EOF )
99 rc = CDK_General_Error;
100 else if( c < req_ver )
101 rc = CDK_Wrong_Format;
102 return rc;
106 static int
107 trustdb_rec_parse( cdk_stream_t buf, tdb_record_t r )
109 size_t n;
110 int recno;
112 if( !buf || !r )
113 return CDK_Inv_Value;
115 recno = cdk_stream_getc( buf );
116 if( recno == EOF )
117 return EOF;
119 switch( recno ) {
120 case TDB_RECORD_TRUST: /* trust record: new */
121 r->recno = 12;
122 r->u.trust.reserved = cdk_stream_getc (buf);
123 n = cdk_stream_read (buf, r->u.trust.fpr, 20);
124 r->u.trust.ownertrust = cdk_stream_getc (buf);
125 r->u.trust.depth = cdk_stream_getc (buf);
126 r->u.trust.validlist = 0;
127 n = 4;
128 while (n--)
129 cdk_stream_getc (buf);
130 n = RECORD_SIZE - 28;
131 while (n--)
132 cdk_stream_getc (buf);
133 if (r->u.trust.ownertrust == EOF)
134 return CDK_EOF;
135 break;
137 case TDB_RECORD_VALID: /* valid record: new */
138 r->recno = 13;
139 r->u.valid.reserved = cdk_stream_getc (buf);
140 n = cdk_stream_read (buf, r->u.valid.fpr, 20);
141 r->u.valid.valid = cdk_stream_getc (buf);
142 r->u.valid.next = 0;
143 n = 4;
144 while (n--)
145 cdk_stream_getc (buf);
146 n = RECORD_SIZE - 27;
147 while (n--)
148 cdk_stream_getc (buf);
149 if (r->u.valid.valid == EOF)
150 return CDK_EOF;
151 break;
153 default:
154 n = RECORD_SIZE - 1;
155 while (n--)
156 cdk_stream_getc (buf);
157 break;
159 r->recno = recno;
160 return 0;
164 tdb_record_t
165 trustdb_rec_byfpr( cdk_stream_t buf, int type,
166 const byte * fpr, size_t fprlen )
168 tdb_record_t rec;
170 if (!fpr || !buf)
171 return NULL;
173 rec = trustdb_rec_new ();
174 if( !rec )
175 return NULL;
177 while( trustdb_rec_parse( buf, rec ) != EOF ) {
178 if( rec->recno != type )
179 continue;
180 switch( type ) {
181 case TDB_RECORD_VALID:
182 if( !memcmp( fpr, rec->u.valid.fpr, fprlen ) )
183 return rec;
184 break;
186 case TDB_RECORD_TRUST:
187 if( !memcmp( rec->u.trust.fpr, fpr, fprlen ) )
188 return rec;
189 break;
192 trustdb_rec_release ( rec );
193 rec = NULL;
194 return rec;
199 cdk_trustdb_get_ownertrust( cdk_stream_t inp, cdk_pkt_pubkey_t pk,
200 int *r_val, int *r_flags )
202 tdb_record_t rec = NULL;
203 byte fpr[20];
204 int flags = 0;
205 int rc;
207 if( !inp || !r_val || !r_flags || !pk )
208 return CDK_Inv_Value;
210 rc = trustdb_check( inp, MIN_TRUSTDB_VER );
211 if( rc )
212 return rc;
214 *r_val = CDK_TRUST_UNKNOWN;
215 cdk_pk_get_fingerprint( pk, fpr );
216 cdk_stream_seek( inp, 0 );
218 rec = trustdb_rec_byfpr( inp, TDB_RECORD_TRUST, fpr, 20 );
219 if( rec ) {
220 *r_val = rec->u.trust.ownertrust & TRUST_MASK;
221 if( *r_val & CDK_TFLAG_REVOKED )
222 flags |= CDK_TFLAG_REVOKED;
223 if( *r_val & CDK_TFLAG_SUB_REVOKED )
224 flags |= CDK_TFLAG_SUB_REVOKED;
225 if( *r_val & CDK_TFLAG_DISABLED )
226 flags |= CDK_TFLAG_DISABLED;
227 *r_flags = flags;
228 rc = 0;
230 trustdb_rec_release( rec );
231 return rc;
236 cdk_trustdb_get_validity( cdk_stream_t inp, cdk_pkt_userid_t id, int *r_val )
238 cdk_md_hd_t rmd;
239 tdb_record_t rec;
240 byte * fpr;
241 int rc;
243 if( !inp || !r_val || !id )
244 return CDK_Inv_Value;
246 rc = trustdb_check( inp, MIN_TRUSTDB_VER );
247 if( rc )
248 return rc;
250 *r_val = CDK_TRUST_UNKNOWN;
251 rmd = cdk_md_open( CDK_MD_RMD160, 0 );
252 if( !rmd )
253 return CDK_Gcry_Error;
255 cdk_md_write( rmd, id->name, id->len );
256 cdk_md_final( rmd );
257 fpr = cdk_md_read( rmd, CDK_MD_RMD160 );
259 cdk_stream_seek( inp, 0 );
260 rec = trustdb_rec_byfpr( inp, TDB_RECORD_VALID, fpr, 20 );
261 if( rec ) {
262 *r_val = rec->u.valid.valid;
263 rc = 0;
266 trustdb_rec_release( rec );
267 cdk_md_close( rmd );
268 return rc;