Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / nettle / pgp-encode.c
blobf84373c0173be2998c6d0db85cfbd3805f8bb57b
1 /* pgp.c
3 * PGP related functions.
4 */
6 /* nettle, low-level cryptographics library
8 * Copyright (C) 2001, 2002 Niels Möller
9 *
10 * The nettle library is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or (at your
13 * option) any later version.
15 * The nettle library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with the nettle library; see the file COPYING.LIB. If not, write to
22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 * MA 02111-1301, USA.
26 #if HAVE_CONFIG_H
27 # include "config.h"
28 #endif
30 #include <assert.h>
31 #include <stdlib.h>
32 #include <string.h>
34 #include "pgp.h"
36 #include "base64.h"
37 #include "buffer.h"
38 #include "macros.h"
39 #include "rsa.h"
41 int
42 pgp_put_uint32(struct nettle_buffer *buffer, uint32_t i)
44 uint8_t *p = nettle_buffer_space(buffer, 4);
45 if (!p)
46 return 0;
48 WRITE_UINT32(p, i);
49 return 1;
52 int
53 pgp_put_uint16(struct nettle_buffer *buffer, unsigned i)
55 uint8_t *p = nettle_buffer_space(buffer, 2);
56 if (!p)
57 return 0;
59 WRITE_UINT16(p, i);
60 return 1;
63 int
64 pgp_put_mpi(struct nettle_buffer *buffer, const mpz_t x)
66 unsigned bits = mpz_sizeinbase(x, 2);
67 unsigned octets = (bits + 7) / 8;
69 uint8_t *p;
71 /* FIXME: What's the correct representation of zero? */
72 if (!pgp_put_uint16(buffer, bits))
73 return 0;
75 p = nettle_buffer_space(buffer, octets);
77 if (!p)
78 return 0;
80 nettle_mpz_get_str_256(octets, p, x);
82 return 1;
85 int
86 pgp_put_string(struct nettle_buffer *buffer,
87 unsigned length,
88 const uint8_t *s)
90 return nettle_buffer_write(buffer, length, s);
93 #if 0
94 static unsigned
95 length_field(unsigned length)
97 if (length < PGP_LENGTH_TWO_OCTET)
98 return 1;
99 else if (length < PGP_LENGTH_FOUR_OCTETS)
100 return 2;
101 else return 4;
103 #endif
105 /* bodyLen = ((1st_octet - 192) << 8) + (2nd_octet) + 192
106 * ==> bodyLen - 192 + 192 << 8 = (1st_octet << 8) + (2nd_octet)
109 #define LENGTH_TWO_OFFSET (192 * 255)
112 pgp_put_length(struct nettle_buffer *buffer,
113 unsigned length)
115 if (length < PGP_LENGTH_TWO_OCTETS)
116 return NETTLE_BUFFER_PUTC(buffer, length);
118 else if (length < PGP_LENGTH_FOUR_OCTETS)
119 return pgp_put_uint16(buffer, length + LENGTH_TWO_OFFSET);
120 else
121 return NETTLE_BUFFER_PUTC(buffer, 0xff) && pgp_put_uint32(buffer, length);
124 /* Uses the "new" packet format */
126 pgp_put_header(struct nettle_buffer *buffer,
127 unsigned tag, unsigned length)
129 assert(tag < 0x40);
131 return (NETTLE_BUFFER_PUTC(buffer, 0xC0 | tag)
132 && pgp_put_length(buffer, length));
135 /* FIXME: Should we abort or return error if the length and the field
136 * size don't match? */
137 void
138 pgp_put_header_length(struct nettle_buffer *buffer,
139 /* start of the header */
140 unsigned start,
141 unsigned field_size)
143 unsigned length;
144 switch (field_size)
146 case 1:
147 length = buffer->size - (start + 2);
148 assert(length < PGP_LENGTH_TWO_OCTETS);
149 buffer->contents[start + 1] = length;
150 break;
151 case 2:
152 length = buffer->size - (start + 3);
153 assert(length < PGP_LENGTH_FOUR_OCTETS
154 && length >= PGP_LENGTH_TWO_OCTETS);
155 WRITE_UINT16(buffer->contents + start + 1, length + LENGTH_TWO_OFFSET);
156 break;
157 case 4:
158 length = buffer->size - (start + 5);
159 WRITE_UINT32(buffer->contents + start + 2, length);
160 break;
161 default:
162 abort();
167 pgp_put_userid(struct nettle_buffer *buffer,
168 unsigned length,
169 const uint8_t *name)
171 return (pgp_put_header(buffer, PGP_TAG_USERID, length)
172 && pgp_put_string(buffer, length, name));
175 unsigned
176 pgp_sub_packet_start(struct nettle_buffer *buffer)
178 return nettle_buffer_space(buffer, 2) ? buffer->size : 0;
182 pgp_put_sub_packet(struct nettle_buffer *buffer,
183 unsigned type,
184 unsigned length,
185 const uint8_t *data)
187 return (pgp_put_length(buffer, length + 1)
188 && NETTLE_BUFFER_PUTC(buffer, type)
189 && pgp_put_string(buffer, length, data));
192 void
193 pgp_sub_packet_end(struct nettle_buffer *buffer, unsigned start)
195 unsigned length;
197 assert(start >= 2);
198 assert(start <= buffer->size);
200 length = buffer->size - start;
201 WRITE_UINT32(buffer->contents + start - 2, length);
205 pgp_put_public_rsa_key(struct nettle_buffer *buffer,
206 const struct rsa_public_key *pub,
207 time_t timestamp)
209 /* Public key packet, version 4 */
210 unsigned start;
211 unsigned length;
213 /* Size of packet is 16 + the size of e and n */
214 length = (4 * 4
215 + nettle_mpz_sizeinbase_256_u(pub->n)
216 + nettle_mpz_sizeinbase_256_u(pub->e));
218 if (!pgp_put_header(buffer, PGP_TAG_PUBLIC_KEY, length))
219 return 0;
221 start = buffer->size;
223 if (! (pgp_put_header(buffer, PGP_TAG_PUBLIC_KEY,
224 /* Assume that we need two octets */
225 PGP_LENGTH_TWO_OCTETS)
226 && pgp_put_uint32(buffer, 4) /* Version */
227 && pgp_put_uint32(buffer, timestamp)/* Time stamp */
228 && pgp_put_uint32(buffer, PGP_RSA) /* Algorithm */
229 && pgp_put_mpi(buffer, pub->n)
230 && pgp_put_mpi(buffer, pub->e)) )
231 return 0;
233 assert(buffer->size == start + length);
235 return 1;
239 pgp_put_rsa_sha1_signature(struct nettle_buffer *buffer,
240 const struct rsa_private_key *key,
241 const uint8_t *keyid,
242 unsigned type,
243 struct sha1_ctx *hash)
245 unsigned signature_start = buffer->size;
246 unsigned hash_end;
247 unsigned sub_packet_start;
248 uint8_t trailer[6];
249 mpz_t s;
251 /* Signature packet. The packet could reasonably be both smaller and
252 * larger than 192, so for simplicity we use the 4 octet header
253 * form. */
255 if (! (pgp_put_header(buffer, PGP_TAG_SIGNATURE, PGP_LENGTH_FOUR_OCTETS)
256 && NETTLE_BUFFER_PUTC(buffer, 4) /* Version */
257 && NETTLE_BUFFER_PUTC(buffer, type)
258 /* Could also be PGP_RSA_SIGN */
259 && NETTLE_BUFFER_PUTC(buffer, PGP_RSA)
260 && NETTLE_BUFFER_PUTC(buffer, PGP_SHA1)
261 && pgp_put_uint16(buffer, 0))) /* Hashed subpacket length */
262 return 0;
264 hash_end = buffer->size;
266 sha1_update(hash,
267 hash_end - signature_start,
268 buffer->contents + signature_start);
270 trailer[0] = 4; trailer[1] = 0xff;
271 WRITE_UINT32(trailer + 2, buffer->size - signature_start);
273 sha1_update(hash, sizeof(trailer), trailer);
276 struct sha1_ctx hcopy = *hash;
277 uint8_t *p = nettle_buffer_space(buffer, 2);
278 if (!p)
279 return 0;
281 sha1_digest(&hcopy, 2, p);
284 /* One "sub-packet" field with the issuer keyid */
285 sub_packet_start = pgp_sub_packet_start(buffer);
286 if (!sub_packet_start)
287 return 0;
289 if (pgp_put_sub_packet(buffer, PGP_SUBPACKET_ISSUER_KEY_ID, 8, keyid))
291 pgp_sub_packet_end(buffer, sub_packet_start);
292 return 0;
295 mpz_init(s);
296 if (!(rsa_sha1_sign(key, hash, s)
297 && pgp_put_mpi(buffer, s)))
299 mpz_clear(s);
300 return 0;
303 mpz_clear(s);
304 pgp_put_header_length(buffer, signature_start, 4);
306 return 1;
309 #define CRC24_INIT 0x0b704ceL
310 #define CRC24_POLY 0x1864cfbL
312 uint32_t
313 pgp_crc24(unsigned length, const uint8_t *data)
315 uint32_t crc = CRC24_INIT;
317 unsigned i;
318 for (i = 0; i<length; i++)
320 unsigned j;
321 crc ^= ((unsigned) (data[i]) << 16);
322 for (j = 0; j<8; j++)
324 crc <<= 1;
325 if (crc & 0x1000000)
326 crc ^= CRC24_POLY;
329 assert(crc < 0x1000000);
330 return crc;
334 #define WRITE(buffer, s) (nettle_buffer_write(buffer, strlen((s)), (s)))
336 /* 15 base 64 groups data per line */
337 #define BINARY_PER_LINE 45
338 #define TEXT_PER_LINE BASE64_ENCODE_LENGTH(BINARY_PER_LINE)
341 pgp_armor(struct nettle_buffer *buffer,
342 const char *tag,
343 unsigned length,
344 const uint8_t *data)
346 struct base64_encode_ctx ctx;
348 unsigned crc = pgp_crc24(length, data);
350 base64_encode_init(&ctx);
352 if (! (WRITE(buffer, "BEGIN PGP ")
353 && WRITE(buffer, tag)
354 && WRITE(buffer, "\nComment: Nettle\n\n")))
355 return 0;
357 for (;
358 length >= BINARY_PER_LINE;
359 length -= BINARY_PER_LINE, data += BINARY_PER_LINE)
361 unsigned done;
362 uint8_t *p
363 = nettle_buffer_space(buffer, TEXT_PER_LINE);
365 if (!p)
366 return 0;
368 done = base64_encode_update(&ctx, p, BINARY_PER_LINE, data);
369 assert(done <= TEXT_PER_LINE);
371 /* FIXME: Create some official way to do this */
372 buffer->size -= (TEXT_PER_LINE - done);
374 if (!NETTLE_BUFFER_PUTC(buffer, '\n'))
375 return 0;
378 if (length)
380 unsigned text_size = BASE64_ENCODE_LENGTH(length)
381 + BASE64_ENCODE_FINAL_LENGTH;
382 unsigned done;
384 uint8_t *p
385 = nettle_buffer_space(buffer, text_size);
386 if (!p)
387 return 0;
389 done = base64_encode_update(&ctx, p, length, data);
390 done += base64_encode_final(&ctx, p + done);
392 /* FIXME: Create some official way to do this */
393 buffer->size -= (text_size - done);
395 if (!NETTLE_BUFFER_PUTC(buffer, '\n'))
396 return 0;
398 /* Checksum */
399 if (!NETTLE_BUFFER_PUTC(buffer, '='))
400 return 0;
403 uint8_t *p = nettle_buffer_space(buffer, 4);
404 if (!p)
405 return 0;
406 base64_encode_group(p, crc);
409 return (WRITE(buffer, "\nBEGIN PGP ")
410 && WRITE(buffer, tag)
411 && NETTLE_BUFFER_PUTC(buffer, '\n'));