root/openpgpsdk/trunk/src/lib/signature.c

Revision 707 (checked in by ben, 1 year ago)

Fixes from Cyril Soler.

Line 
1 /*
2  * Copyright (c) 2005-2009 Nominet UK (www.nic.uk)
3  * All rights reserved.
4  * Contributors: Ben Laurie, Rachel Willmer, Alasdair Mackintosh.
5  * The Contributors have asserted their moral rights under the
6  * UK Copyright Design and Patents Act 1988 to
7  * be recorded as the authors of this copyright work.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
10  * use this file except in compliance with the License.
11  *
12  * You may obtain a copy of the License at
13  *     http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  *
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  */
22
23 /** \file
24  */
25
26 #include <openpgpsdk/signature.h>
27 #include <openpgpsdk/readerwriter.h>
28 #include <openpgpsdk/crypto.h>
29 #include <openpgpsdk/create.h>
30 #include <openpgpsdk/literal.h>
31 #include <openpgpsdk/partial.h>
32 #include <openpgpsdk/writer_armoured.h>
33
34 #include <assert.h>
35 #include <string.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38
39 #include <openpgpsdk/final.h>
40
41 #include <openssl/dsa.h>
42
43 static int debug=0;
44 #define MAXBUF 1024 /*<! Standard buffer size to use */
45
46 /** \ingroup Core_Create
47  * needed for signature creation
48  */
49 struct ops_create_signature
50     {
51     ops_hash_t hash;
52     ops_signature_t sig;
53     ops_memory_t *mem;
54     ops_create_info_t *info; /*!< how to do the writing */
55     unsigned hashed_count_offset;
56     unsigned hashed_data_length;
57     unsigned unhashed_count_offset;
58     };
59
60 /**
61    \ingroup Core_Signature
62    Creates new ops_create_signature_t
63    \return new ops_create_signature_t
64    \note It is the caller's responsibility to call ops_create_signature_delete()
65    \sa ops_create_signature_delete()
66 */
67 ops_create_signature_t *ops_create_signature_new()
68     { return ops_mallocz(sizeof(ops_create_signature_t)); }
69
70 /**
71    \ingroup Core_Signature
72    Free signature and memory associated with it
73    \param sig struct to free
74    \sa ops_create_signature_new()
75 */
76 void ops_create_signature_delete(ops_create_signature_t *sig)
77     {
78     ops_create_info_delete(sig->info);
79     sig->info=NULL;
80     free(sig);
81     }
82
83 static unsigned char prefix_md5[]={ 0x30,0x20,0x30,0x0C,0x06,0x08,0x2A,0x86,
84                                     0x48,0x86,0xF7,0x0D,0x02,0x05,0x05,0x00,
85                                     0x04,0x10 };
86
87 static unsigned char prefix_sha1[]={ 0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0E,
88                                      0x03,0x02,0x1A,0x05,0x00,0x04,0x14 };
89
90 static unsigned char prefix_sha256[]={ 0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,
91                                        0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,
92                                        0x00,0x04,0x20 };
93
94 /**
95    \ingroup Core_Create
96    implementation of EMSA-PKCS1-v1_5, as defined in OpenPGP RFC
97    \param M
98    \param mLen
99    \param hash_alg Hash algorithm to use
100    \param EM
101    \return ops_true if OK; else ops_false
102 */
103 ops_boolean_t encode_hash_buf(const unsigned char *M, size_t mLen,
104                               const ops_hash_algorithm_t hash_alg,
105                               unsigned char* EM)
106     {
107     // implementation of EMSA-PKCS1-v1_5, as defined in OpenPGP RFC
108
109     unsigned i;
110     int n;
111     ops_hash_t hash;
112     int hash_sz=0;
113     //    int encoded_hash_sz=0;
114     int prefix_sz=0;
115     unsigned padding_sz=0;
116     unsigned encoded_msg_sz=0;
117     unsigned char* prefix=NULL;
118
119     assert(hash_alg == OPS_HASH_SHA1);
120
121     // 1. Apply hash function to M
122
123     ops_hash_any(&hash, hash_alg);
124     hash.init(&hash);
125     hash.add(&hash, M, mLen);
126
127     // \todo combine with rsa_sign
128
129     // 2. Get hash prefix
130
131     switch(hash_alg)
132         {
133     case OPS_HASH_SHA1:
134         prefix=prefix_sha1;
135         prefix_sz=sizeof prefix_sha1;
136         hash_sz=OPS_SHA1_HASH_SIZE;
137         //        encoded_hash_sz=hash_sz+prefix_sz;
138         // \todo why is Ben using a PS size of 90 in rsa_sign?
139         // (keysize-hashsize-1-2)
140         padding_sz=90;
141         break;
142
143     default:
144         assert(0);
145         }
146
147     // \todo 3. Test for len being too short
148
149     // 4 and 5. Generate PS and EM
150
151     EM[0]=0x00;
152     EM[1]=0x01;
153
154     for (i=0; i<padding_sz; i++)
155         EM[2+i]=0xFF;
156
157     i+=2;
158
159     EM[i++]=0x00;
160
161     memcpy(&EM[i], prefix, prefix_sz);
162     i+=prefix_sz;
163
164     // finally, write out hashed result
165     
166     n=hash.finish(&hash, &EM[i]);
167     assert(n == hash_sz);
168
169     encoded_msg_sz=i+hash_sz-1;
170
171     // \todo test n for OK response?
172
173     if (debug)
174         {
175         fprintf(stderr, "Encoded Message: \n");
176         for (i=0; i<encoded_msg_sz; i++)
177             fprintf(stderr, "%2x ", EM[i]);
178         fprintf(stderr, "\n");
179         }
180
181     return ops_true;
182     }
183
184 // XXX: both this and verify would be clearer if the signature were
185 // treated as an MPI.
186 static void rsa_sign(ops_hash_t *hash, const ops_rsa_public_key_t *rsa,
187                      const ops_rsa_secret_key_t *srsa, ops_create_info_t *opt)
188     {
189     unsigned char hashbuf[8192];
190     unsigned char sigbuf[8192];
191     unsigned keysize;
192     unsigned hashsize;
193     unsigned n;
194     unsigned t;
195     BIGNUM *bn;
196
197     // XXX: we assume hash is sha-1 for now
198     hashsize=20+sizeof prefix_sha1;
199
200     keysize=BN_num_bytes(rsa->n);
201     assert(keysize <= sizeof hashbuf);
202     assert(10+hashsize <= keysize);
203
204     hashbuf[0]=0;
205     hashbuf[1]=1;
206     if (debug)
207         printf("rsa_sign: PS is %d\n", keysize-hashsize-1-2);
208     for(n=2 ; n < keysize-hashsize-1 ; ++n)
209         hashbuf[n]=0xff;
210     hashbuf[n++]=0;
211
212     memcpy(&hashbuf[n], prefix_sha1, sizeof prefix_sha1);
213     n+=sizeof prefix_sha1;
214
215     t=hash->finish(hash, &hashbuf[n]);
216     assert(t == 20);
217
218     ops_write(&hashbuf[n], 2, opt);
219
220     n+=t;
221     assert(n == keysize);
222
223     t=ops_rsa_private_encrypt(sigbuf, hashbuf, keysize, srsa, rsa);
224     bn=BN_bin2bn(sigbuf, t, NULL);
225     ops_write_mpi(bn, opt);
226     BN_free(bn);
227     }
228
229 static void dsa_sign(ops_hash_t *hash, const ops_dsa_public_key_t *dsa,
230                      const ops_dsa_secret_key_t *sdsa, ops_create_info_t *cinfo)
231     {
232     unsigned char hashbuf[8192];
233     unsigned hashsize;
234     unsigned t;
235
236     // hashsize must be "equal in size to the number of bits of q,
237     // the group generated by the DSA key's generator value
238     // 160/8 = 20
239
240     hashsize=20;
241
242     // finalise hash
243     t=hash->finish(hash, &hashbuf[0]);
244     assert(t == 20);
245
246     ops_write(&hashbuf[0], 2, cinfo);
247
248     // write signature to buf
249     DSA_SIG* dsasig;
250     dsasig=ops_dsa_sign(hashbuf, hashsize, sdsa, dsa);
251
252     // convert and write the sig out to memory
253     ops_write_mpi(dsasig->r, cinfo);
254     ops_write_mpi(dsasig->s, cinfo);
255     DSA_SIG_free(dsasig);
256     }
257
258 static ops_boolean_t rsa_verify(ops_hash_algorithm_t type,
259                                 const unsigned char *hash, size_t hash_length,
260                                 const ops_rsa_signature_t *sig,
261                                 const ops_rsa_public_key_t *rsa)
262     {
263     unsigned char sigbuf[8192];
264     unsigned char hashbuf_from_sig[8192];
265     unsigned n;
266     unsigned keysize;
267     unsigned char *prefix;
268     int plen;
269
270     keysize=BN_num_bytes(rsa->n);
271     /* RSA key can't be bigger than 65535 bits, so... */
272     assert(keysize <= sizeof hashbuf_from_sig);
273     assert((unsigned)BN_num_bits(sig->sig) <= 8*sizeof sigbuf);
274     BN_bn2bin(sig->sig, sigbuf);
275
276     n=ops_rsa_public_decrypt(hashbuf_from_sig, sigbuf, BN_num_bytes(sig->sig),
277                              rsa);
278     int debug_len_decrypted=n;
279
280     if(n != keysize) // obviously, this includes error returns
281         return ops_false;
282
283     // XXX: why is there a leading 0? The first byte should be 1...
284     // XXX: because the decrypt should use keysize and not sigsize?
285     if(hashbuf_from_sig[0] != 0 || hashbuf_from_sig[1] != 1)
286         return ops_false;
287
288     switch(type)
289         {
290     case OPS_HASH_MD5: prefix=prefix_md5; plen=sizeof prefix_md5; break;
291     case OPS_HASH_SHA1: prefix=prefix_sha1; plen=sizeof prefix_sha1; break;
292     case OPS_HASH_SHA256: prefix=prefix_sha256; plen=sizeof prefix_sha256; break;
293     default: assert(0); break;
294         }
295
296     if(keysize-plen-hash_length < 10)
297         return ops_false;
298
299     for(n=2 ; n < keysize-plen-hash_length-1 ; ++n)
300         if(hashbuf_from_sig[n] != 0xff)
301             return ops_false;
302
303     if(hashbuf_from_sig[n++] != 0)
304         return ops_false;
305
306     if (debug)
307         {
308         int zz;
309
310         printf("\n");
311         printf("hashbuf_from_sig\n");
312         for (zz=0; zz<debug_len_decrypted; zz++)
313             printf("%02x ", hashbuf_from_sig[n+zz]);
314         printf("\n");
315         printf("prefix\n");
316         for (zz=0; zz<plen; zz++)
317             printf("%02x ", prefix[zz]);
318         printf("\n");
319
320         printf("\n");
321         printf("hash from sig\n");
322         unsigned uu;
323         for (uu=0; uu<hash_length; uu++)
324             printf("%02x ", hashbuf_from_sig[n+plen+uu]);
325         printf("\n");
326         printf("hash passed in (should match hash from sig)\n");
327         for (uu=0; uu<hash_length; uu++)
328             printf("%02x ", hash[uu]);
329         printf("\n");
330         }
331     if(memcmp(&hashbuf_from_sig[n], prefix, plen)
332        || memcmp(&hashbuf_from_sig[n+plen], hash, hash_length))
333         return ops_false;
334
335     return ops_true;
336     }
337
338 static void hash_add_key(ops_hash_t *hash, const ops_public_key_t *key)
339     {
340     ops_memory_t *mem=ops_memory_new();
341     size_t l;
342
343     ops_build_public_key(mem, key, ops_false);
344
345     l=ops_memory_get_length(mem);
346     ops_hash_add_int(hash, 0x99, 1);
347     ops_hash_add_int(hash, l, 2);
348     hash->add(hash, ops_memory_get_data(mem), l);
349
350     ops_memory_free(mem);
351     }
352
353 static void initialise_hash(ops_hash_t *hash, const ops_signature_t *sig)
354     {
355     ops_hash_any(hash, sig->info.hash_algorithm);
356     hash->init(hash);
357     }
358
359 static void init_key_signature(ops_hash_t *hash, const ops_signature_t *sig,
360                                const ops_public_key_t *key)
361     {
362     initialise_hash(hash, sig);
363     hash_add_key(hash, key);
364     }
365
366 static void hash_add_trailer(ops_hash_t *hash, const ops_signature_t *sig,
367                              const unsigned char *raw_packet)
368     {
369     if(sig->info.version == OPS_V4)
370         {
371         if(raw_packet)
372             hash->add(hash, raw_packet+sig->v4_hashed_data_start,
373                       sig->info.v4_hashed_data_length);
374         ops_hash_add_int(hash, sig->info.version, 1);
375         ops_hash_add_int(hash, 0xff, 1);
376         ops_hash_add_int(hash, sig->info.v4_hashed_data_length, 4);
377         }
378     else
379         {
380         ops_hash_add_int(hash, sig->info.type, 1);
381         ops_hash_add_int(hash, sig->info.creation_time, 4);
382         }
383     }
384
385 /**
386    \ingroup Core_Signature
387    \brief Checks a signature
388    \param hash Signature Hash to be checked
389    \param length Signature Length
390    \param sig The Signature to be checked
391    \param signer The signer's public key
392    \return ops_true if good; else ops_false
393 */
394 ops_boolean_t ops_check_signature(const unsigned char *hash, unsigned length,
395                                      const ops_signature_t *sig,
396                                      const ops_public_key_t *signer)
397     {
398     ops_boolean_t ret;
399
400     /*
401     printf(" hash=");
402     //    hashout[0]=0;
403     hexdump(hash,length);
404     */
405
406     switch(sig->info.key_algorithm)
407         {
408     case OPS_PKA_DSA:
409         ret=ops_dsa_verify(hash, length, &sig->info.signature.dsa,
410                            &signer->key.dsa);
411         break;
412
413     case OPS_PKA_RSA:
414         ret=rsa_verify(sig->info.hash_algorithm, hash, length,
415                        &sig->info.signature.rsa, &signer->key.rsa);
416         break;
417
418     default:
419         assert(0);
420         }
421
422     return ret;
423     }
424
425 static ops_boolean_t hash_and_check_signature(ops_hash_t *hash,
426                                               const ops_signature_t *sig,
427                                               const ops_public_key_t *signer)
428     {
429     int n;
430     unsigned char hashout[OPS_MAX_HASH_SIZE];
431
432     n=hash->finish(hash, hashout);
433
434     return ops_check_signature(hashout, n, sig, signer);
435     }
436
437 static ops_boolean_t finalise_signature(ops_hash_t *hash,
438                                         const ops_signature_t *sig,
439                                         const ops_public_key_t *signer,
440                                         const unsigned char *raw_packet)
441     {
442     hash_add_trailer(hash, sig, raw_packet);
443     return hash_and_check_signature(hash, sig, signer);
444     }
445
446 /**
447  * \ingroup Core_Signature
448  *
449  * \brief Verify a certification signature.
450  *
451  * \param key The public key that was signed.
452  * \param id The user ID that was signed
453  * \param sig The signature.
454  * \param signer The public key of the signer.
455  * \param raw_packet The raw signature packet.
456  * \return ops_true if OK; else ops_false
457  */
458 ops_boolean_t
459 ops_check_user_id_certification_signature(const ops_public_key_t *key,
460                                           const ops_user_id_t *id,
461                                           const ops_signature_t *sig,
462                                           const ops_public_key_t *signer,
463                                           const unsigned char *raw_packet)
464     {
465     ops_hash_t hash;
466     size_t user_id_len=strlen((char *)id->user_id);
467
468     init_key_signature(&hash, sig, key);
469
470     if(sig->info.version == OPS_V4)
471         {
472         ops_hash_add_int(&hash, 0xb4, 1);
473         ops_hash_add_int(&hash, user_id_len, 4);
474         }
475     hash.add(&hash, id->user_id, user_id_len);
476
477     return finalise_signature(&hash, sig, signer, raw_packet);
478     }
479
480 /**
481  * \ingroup Core_Signature
482  *
483  * Verify a certification signature.
484  *
485  * \param key The public key that was signed.
486  * \param attribute The user attribute that was signed
487  * \param sig The signature.
488  * \param signer The public key of the signer.
489  * \param raw_packet The raw signature packet.
490  * \return ops_true if OK; else ops_false
491  */
492 ops_boolean_t
493 ops_check_user_attribute_certification_signature(const ops_public_key_t *key,
494                                           const ops_user_attribute_t *attribute,
495                                           const ops_signature_t *sig,
496                                           const ops_public_key_t *signer,
497                                           const unsigned char *raw_packet)
498     {
499     ops_hash_t hash;
500
501     init_key_signature(&hash, sig, key);
502
503     if(sig->info.version == OPS_V4)
504         {
505         ops_hash_add_int(&hash, 0xd1, 1);
506         ops_hash_add_int(&hash, attribute->data.len, 4);
507         }
508     hash.add(&hash, attribute->data.contents, attribute->data.len);
509
510     return finalise_signature(&hash, sig, signer, raw_packet);
511     }
512
513 /**
514  * \ingroup Core_Signature
515  *
516  * Verify a subkey signature.
517  *
518  * \param key The public key whose subkey was signed.
519  * \param subkey The subkey of the public key that was signed.
520  * \param sig The signature.
521  * \param signer The public key of the signer.
522  * \param raw_packet The raw signature packet.
523  * \return ops_true if OK; else ops_false
524  */
525 ops_boolean_t
526 ops_check_subkey_signature(const ops_public_key_t *key,
527                            const ops_public_key_t *subkey,
528                            const ops_signature_t *sig,
529                            const ops_public_key_t *signer,
530                            const unsigned char *raw_packet)
531     {
532     ops_hash_t hash;
533
534     init_key_signature(&hash, sig, key);
535     hash_add_key(&hash, subkey);
536
537     return finalise_signature(&hash, sig, signer, raw_packet);
538     }
539
540 /**
541  * \ingroup Core_Signature
542  *
543  * Verify a direct signature.
544  *
545  * \param key The public key which was signed.
546  * \param sig The signature.
547  * \param signer The public key of the signer.
548  * \param raw_packet The raw signature packet.
549  * \return ops_true if OK; else ops_false
550  */
551 ops_boolean_t
552 ops_check_direct_signature(const ops_public_key_t *key,
553                            const ops_signature_t *sig,
554                            const ops_public_key_t *signer,
555                            const unsigned char *raw_packet)
556     {
557     ops_hash_t hash;
558
559     init_key_signature(&hash, sig, key);
560     return finalise_signature(&hash, sig, signer, raw_packet);
561     }
562
563 /**
564  * \ingroup Core_Signature
565  *
566  * Verify a signature on a hash (the hash will have already been fed
567  * the material that was being signed, for example signed cleartext).
568  *
569  * \param hash A hash structure of appropriate type that has been fed
570  * the material to be signed. This MUST NOT have been finalised.
571  * \param sig The signature to be verified.
572  * \param signer The public key of the signer.
573  * \return ops_true if OK; else ops_false
574  */
575 ops_boolean_t
576 ops_check_hash_signature(ops_hash_t *hash, const ops_signature_t *sig,
577                          const ops_public_key_t *signer)
578     {
579     if(sig->info.hash_algorithm != hash->algorithm)
580         return ops_false;
581
582     return finalise_signature(hash, sig, signer, NULL);
583     }
584
585 static void start_signature_in_mem(ops_create_signature_t *sig)
586     {
587     // since this has subpackets and stuff, we have to buffer the whole
588     // thing to get counts before writing.
589     sig->mem=ops_memory_new();
590     ops_memory_init(sig->mem, 100);
591     ops_writer_set_memory(sig->info, sig->mem);
592
593     // write nearly up to the first subpacket
594     ops_write_scalar(sig->sig.info.version, 1, sig->info);
595     ops_write_scalar(sig->sig.info.type, 1, sig->info);
596     ops_write_scalar(sig->sig.info.key_algorithm, 1, sig->info);
597     ops_write_scalar(sig->sig.info.hash_algorithm, 1, sig->info);
598
599     // dummy hashed subpacket count
600     sig->hashed_count_offset=ops_memory_get_length(sig->mem);
601     ops_write_scalar(0, 2, sig->info);
602     }   
603
604 /**
605  * \ingroup Core_Signature
606  *
607  * ops_signature_start() creates a V4 public key signature with a SHA1 hash.
608  *
609  * \param sig The signature structure to initialise
610  * \param key The public key to be signed
611  * \param id The user ID being bound to the key
612  * \param type Signature type
613  */
614 void ops_signature_start_key_signature(ops_create_signature_t *sig,
615                                        const ops_public_key_t *key,
616                                        const ops_user_id_t *id,
617                                        ops_sig_type_t type)
618     {
619     sig->info=ops_create_info_new();
620
621     // XXX: refactor with check (in several ways - check should probably
622     // use the buffered writer to construct packets (done), and also should
623     // share code for hash calculation)
624     sig->sig.info.version=OPS_V4;
625     sig->sig.info.hash_algorithm=OPS_HASH_SHA1;
626     sig->sig.info.key_algorithm=key->algorithm;
627     sig->sig.info.type=type;
628
629     sig->hashed_data_length=-1;
630
631     init_key_signature(&sig->hash, &sig->sig, key);
632
633     ops_hash_add_int(&sig->hash, 0xb4, 1);
634     ops_hash_add_int(&sig->hash, strlen((char *)id->user_id), 4);
635     sig->hash.add(&sig->hash, id->user_id, strlen((char *)id->user_id));
636
637     start_signature_in_mem(sig);
638     }
639
640 /**
641  * \ingroup Core_Signature
642  *
643  * Create a V4 public key signature over some cleartext.
644  *
645  * \param sig The signature structure to initialise
646  * \param id
647  * \param type
648  * \todo Expand description. Allow other hashes.
649  */
650
651 static void ops_signature_start_signature(ops_create_signature_t *sig,
652                                           const ops_secret_key_t *key,
653                                           const ops_hash_algorithm_t hash,
654                                           const ops_sig_type_t type)
655     {
656     sig->info=ops_create_info_new();
657
658     // XXX: refactor with check (in several ways - check should probably
659     // use the buffered writer to construct packets (done), and also should
660     // share code for hash calculation)
661     sig->sig.info.version=OPS_V4;
662     sig->sig.info.key_algorithm=key->public_key.algorithm;
663     sig->sig.info.hash_algorithm=hash;
664     sig->sig.info.type=type;
665
666     sig->hashed_data_length=-1;
667
668     if (debug)
669         { fprintf(stderr, "initialising hash for sig in mem\n"); }
670     initialise_hash(&sig->hash, &sig->sig);
671     start_signature_in_mem(sig);
672     }
673
674 /**
675  * \ingroup Core_Signature
676  * \brief Setup to start a cleartext's signature
677  */
678 void ops_signature_start_cleartext_signature(ops_create_signature_t *sig,
679                                              const ops_secret_key_t *key,
680                                              const ops_hash_algorithm_t hash,
681                                              const ops_sig_type_t type)
682     {
683     ops_signature_start_signature(sig, key, hash, type);
684     }
685
686 /**
687  * \ingroup Core_Signature
688  * \brief Setup to start a message's signature
689  */
690 void ops_signature_start_message_signature(ops_create_signature_t *sig,
691                                            const ops_secret_key_t *key,
692                                            const ops_hash_algorithm_t hash,
693                                            const ops_sig_type_t type)
694     {
695     ops_signature_start_signature(sig, key, hash, type);
696     }
697
698 /**
699  * \ingroup Core_Signature
700  *
701  * Add plaintext data to a signature-to-be.
702  *
703  * \param sig The signature-to-be.
704  * \param buf The plaintext data.
705  * \param length The amount of plaintext data.
706  */
707 void ops_signature_add_data(ops_create_signature_t *sig, const void *buf,
708                             size_t length)
709     {
710     if (debug)
711         { fprintf(stderr, "ops_signature_add_data adds to hash\n"); }
712     sig->hash.add(&sig->hash, buf, length);
713     }
714
715 /**
716  * \ingroup Core_Signature
717  *
718  * Mark the end of the hashed subpackets in the signature
719  *
720  * \param sig
721  */
722
723 ops_boolean_t ops_signature_hashed_subpackets_end(ops_create_signature_t *sig)
724     {
725     sig->hashed_data_length=ops_memory_get_length(sig->mem)
726         -sig->hashed_count_offset-2;
727     ops_memory_place_int(sig->mem, sig->hashed_count_offset,
728                          sig->hashed_data_length, 2);
729     // dummy unhashed subpacket count
730     sig->unhashed_count_offset=ops_memory_get_length(sig->mem);
731     return ops_write_scalar(0, 2, sig->info);
732     }
733
734 /**
735  * \ingroup Core_Signature
736  *
737  * Write out a signature
738  *
739  * \param sig
740  * \param key
741  * \param skey
742  * \param info
743  *
744  */
745
746 ops_boolean_t ops_write_signature(ops_create_signature_t *sig,
747                                   const ops_public_key_t *key,
748                                   const ops_secret_key_t *skey,
749                                   ops_create_info_t *info)
750     {
751     ops_boolean_t rtn=ops_false;
752     size_t l=ops_memory_get_length(sig->mem);
753
754     // check key not decrypted
755     switch (skey->public_key.algorithm)
756         {
757     case OPS_PKA_RSA:
758     case OPS_PKA_RSA_ENCRYPT_ONLY:
759     case OPS_PKA_RSA_SIGN_ONLY:
760         assert(skey->key.rsa.d);
761         break;
762
763     case OPS_PKA_DSA:
764         assert(skey->key.dsa.x);
765         break;
766
767     default:
768         fprintf(stderr, "Unsupported algorithm %d\n",
769                 skey->public_key.algorithm);
770         assert(0);
771         }
772
773     assert(sig->hashed_data_length != (unsigned)-1);
774
775     ops_memory_place_int(sig->mem, sig->unhashed_count_offset,
776                          l-sig->unhashed_count_offset-2, 2);
777
778     // add the packet from version number to end of hashed subpackets
779
780     if (debug)
781         { fprintf(stderr, "--- Adding packet to hash from version number to"
782                   " hashed subpkts\n"); }
783
784     sig->hash.add(&sig->hash, ops_memory_get_data(sig->mem),
785                   sig->unhashed_count_offset);
786
787     // add final trailer
788     ops_hash_add_int(&sig->hash, sig->sig.info.version, 1);
789     ops_hash_add_int(&sig->hash, 0xff, 1);
790     // +6 for version, type, pk alg, hash alg, hashed subpacket length
791     ops_hash_add_int(&sig->hash, sig->hashed_data_length+6, 4);
792
793     if (debug)
794         { fprintf(stderr, "--- Finished adding packet to hash from version"
795                   " number to hashed subpkts\n"); }
796
797     // XXX: technically, we could figure out how big the signature is
798     // and write it directly to the output instead of via memory.
799     switch(skey->public_key.algorithm)
800         {
801     case OPS_PKA_RSA:
802     case OPS_PKA_RSA_ENCRYPT_ONLY:
803     case OPS_PKA_RSA_SIGN_ONLY:
804         rsa_sign(&sig->hash, &key->key.rsa, &skey->key.rsa, sig->info);
805         break;
806
807     case OPS_PKA_DSA:
808         dsa_sign(&sig->hash, &key->key.dsa, &skey->key.dsa, sig->info);
809         break;
810
811     default:
812         fprintf(stderr, "Unsupported algorithm %d\n",
813                 skey->public_key.algorithm);
814         assert(0);
815         }
816
817     rtn=ops_write_ptag(OPS_PTAG_CT_SIGNATURE, info);
818     if (rtn)
819         {
820         l=ops_memory_get_length(sig->mem);
821         rtn = ops_write_length(l, info)
822             && ops_write(ops_memory_get_data(sig->mem), l, info);
823         }
824
825     ops_memory_free(sig->mem);
826
827     if (!rtn)
828         OPS_ERROR(&info->errors, OPS_E_W, "Cannot write signature");
829     return rtn;
830     }
831
832 /**
833  * \ingroup Core_Signature
834  *
835  * ops_signature_add_creation_time() adds a creation time to the signature.
836  *
837  * \param sig
838  * \param when
839  */
840 ops_boolean_t ops_signature_add_creation_time(ops_create_signature_t *sig,
841                                               time_t when)
842     {
843     return ops_write_ss_header(5, OPS_PTAG_SS_CREATION_TIME, sig->info)
844         && ops_write_scalar(when, 4, sig->info);
845     }
846
847 /**
848  * \ingroup Core_Signature
849  *
850  * Adds issuer's key ID to the signature
851  *
852  * \param sig
853  * \param keyid
854  */
855
856 ops_boolean_t
857 ops_signature_add_issuer_key_id(ops_create_signature_t *sig,
858                                 const unsigned char keyid[OPS_KEY_ID_SIZE])
859     {
860     return ops_write_ss_header(OPS_KEY_ID_SIZE+1, OPS_PTAG_SS_ISSUER_KEY_ID,
861                                sig->info)
862         && ops_write(keyid, OPS_KEY_ID_SIZE, sig->info);
863     }
864
865 /**
866  * \ingroup Core_Signature
867  *
868  * Adds primary user ID to the signature
869  *
870  * \param sig
871  * \param primary
872  */
873 void ops_signature_add_primary_user_id(ops_create_signature_t *sig,
874                                        ops_boolean_t primary)
875     {
876     ops_write_ss_header(2, OPS_PTAG_SS_PRIMARY_USER_ID, sig->info);
877     ops_write_scalar(primary, 1, sig->info);
878     }
879
880 /**
881  * \ingroup Core_Signature
882  *
883  * Get the hash structure in use for the signature.
884  *
885  * \param sig The signature structure.
886  * \return The hash structure.
887  */
888 ops_hash_t *ops_signature_get_hash(ops_create_signature_t *sig)
889     { return &sig->hash; }
890
891 static int open_output_file(ops_create_info_t **cinfo,
892                             const char* input_filename,
893                             const char* output_filename,
894                             const ops_boolean_t use_armour,
895                             const ops_boolean_t overwrite)
896     {
897     int fd_out;
898
899     // setup output file
900
901     if (output_filename)
902         fd_out=ops_setup_file_write(cinfo, output_filename, overwrite);
903     else
904         {
905         char *myfilename=NULL;
906         unsigned filenamelen=strlen(input_filename)+4+1;
907         myfilename=ops_mallocz(filenamelen);
908         if (use_armour)
909             snprintf(myfilename, filenamelen, "%s.asc", input_filename);
910         else
911             snprintf(myfilename, filenamelen, "%s.gpg", input_filename);
912         fd_out=ops_setup_file_write(cinfo,  myfilename,  overwrite);
913         free(myfilename);
914         }
915
916     return fd_out;
917     }
918
919 /**
920    \ingroup HighLevel_Sign
921    \brief Sign a file with a Cleartext Signature
922    \param input_filename Name of file to be signed
923    \param output_filename Filename to be created. If NULL, filename will be constructed from the input_filename.
924    \param skey Secret Key to sign with
925    \param overwrite Allow output file to be overwritten, if set
926    \return ops_true if OK, else ops_false
927
928    Example code:
929    \code
930    void example(const ops_secret_key_t *skey, ops_boolean_t overwrite)
931    {
932    if (ops_sign_file_as_cleartext("mytestfile.txt",NULL,skey,overwrite)==ops_true)
933        printf("OK");
934    else
935        printf("ERR");
936    }
937    \endcode
938 */
939 ops_boolean_t ops_sign_file_as_cleartext(const char* input_filename,
940                                          const char* output_filename,
941                                          const ops_secret_key_t *skey,
942                                          const ops_boolean_t overwrite)
943     {
944     // \todo allow choice of hash algorithams
945     // enforce use of SHA1 for now
946
947     unsigned char keyid[OPS_KEY_ID_SIZE];
948     ops_create_signature_t *sig=NULL;
949
950     int fd_in=0;
951     int fd_out=0;
952     ops_create_info_t *cinfo=NULL;
953     unsigned char buf[MAXBUF];
954     //int flags=0;
955     ops_boolean_t rtn=ops_false;
956     ops_boolean_t use_armour=ops_true;
957
958     // open file to sign
959     fd_in=open(input_filename, O_RDONLY | O_BINARY);
960     if(fd_in < 0)
961         {
962         return ops_false;
963         }
964    
965     // set up output file
966
967     fd_out=open_output_file(&cinfo, input_filename, output_filename, use_armour,
968                             overwrite);
969
970     if (fd_out < 0)
971         {
972         close(fd_in);
973         return ops_false;
974         }
975
976     // set up signature
977     sig=ops_create_signature_new();
978     if (!sig)
979         {
980         close (fd_in);
981         ops_teardown_file_write(cinfo, fd_out);
982         return ops_false;
983         }
984
985     // \todo could add more error detection here
986     ops_signature_start_cleartext_signature(sig, skey,
987                                             OPS_HASH_SHA1, OPS_SIG_BINARY);
988     if (!ops_writer_push_clearsigned(cinfo, sig))
989         return ops_false;
990
991     // Do the signing
992
993     for (;;)
994         {
995         int n=0;
996    
997         n=read(fd_in, buf, sizeof(buf));
998         if (!n)
999             break;
1000         assert(n>=0);
1001         ops_write(buf, n, cinfo);
1002         }
1003     close(fd_in);
1004
1005     // add signature with subpackets:
1006     // - creation time
1007     // - key id
1008     rtn = ops_writer_switch_to_armoured_signature(cinfo)
1009         && ops_signature_add_creation_time(sig, time(NULL));
1010     if (!rtn)
1011         {
1012         ops_teardown_file_write(cinfo, fd_out);
1013         return ops_false;
1014         }
1015
1016     ops_keyid(keyid, &skey->public_key);
1017
1018     rtn = ops_signature_add_issuer_key_id(sig, keyid)
1019         && ops_signature_hashed_subpackets_end(sig)
1020         && ops_write_signature(sig, &skey->public_key, skey, cinfo);
1021
1022     ops_teardown_file_write(cinfo, fd_out);
1023
1024     if (!rtn)
1025         OPS_ERROR(&cinfo->errors, OPS_E_W, "Cannot sign file as cleartext");
1026     return rtn;
1027     }
1028
1029
1030 /**
1031  * \ingroup HighLevel_Sign
1032  * \brief Sign a buffer with a Cleartext signature
1033  * \param cleartext Text to be signed
1034  * \param len Length of text
1035  * \param signed_cleartext ops_memory_t struct in which to write the signed cleartext
1036  * \param skey Secret key with which to sign the cleartext
1037  * \return ops_true if OK; else ops_false
1038
1039  * \note It is the calling function's responsibility to free signed_cleartext
1040  * \note signed_cleartext should be a NULL pointer when passed in
1041
1042  Example code:
1043  \code
1044  void example(const ops_secret_key_t *skey)
1045  {
1046    ops_memory_t* mem=NULL;
1047    const char* buf="Some example text";
1048    size_t len=strlen(buf);
1049    if (ops_sign_buf_as_cleartext(buf,len, &mem, skey)==ops_true)
1050      printf("OK");
1051    else
1052      printf("ERR");
1053    // free signed cleartext after use
1054    ops_memory_free(mem);
1055  }
1056  \endcode
1057  */
1058 ops_boolean_t ops_sign_buf_as_cleartext(const char* cleartext, const size_t len,
1059                                         ops_memory_t** signed_cleartext,
1060                                         const ops_secret_key_t *skey)
1061     {
1062     ops_boolean_t rtn=ops_false;
1063
1064     // \todo allow choice of hash algorithams
1065     // enforce use of SHA1 for now
1066
1067     unsigned char keyid[OPS_KEY_ID_SIZE];
1068     ops_create_signature_t *sig=NULL;
1069
1070     ops_create_info_t *cinfo=NULL;
1071    
1072     assert(*signed_cleartext == NULL);
1073
1074     // set up signature
1075     sig=ops_create_signature_new();
1076     if (!sig)
1077         return ops_false;
1078
1079     // \todo could add more error detection here
1080     ops_signature_start_cleartext_signature(sig, skey, OPS_HASH_SHA1,
1081                                             OPS_SIG_BINARY);
1082
1083     // set up output file
1084     ops_setup_memory_write(&cinfo, signed_cleartext, len);
1085
1086     // Do the signing
1087     // add signature with subpackets:
1088     // - creation time
1089     // - key id
1090     rtn = ops_writer_push_clearsigned(cinfo, sig)
1091         && ops_write(cleartext, len, cinfo)
1092         && ops_writer_switch_to_armoured_signature(cinfo)
1093         && ops_signature_add_creation_time(sig, time(NULL));
1094
1095     if (!rtn)
1096         return ops_false;
1097
1098     ops_keyid(keyid, &skey->public_key);
1099
1100     rtn = ops_signature_add_issuer_key_id(sig, keyid)
1101         && ops_signature_hashed_subpackets_end(sig)
1102         && ops_write_signature(sig, &skey->public_key, skey, cinfo)
1103         && ops_writer_close(cinfo);
1104
1105     // Note: the calling function must free signed_cleartext
1106     ops_create_info_delete(cinfo);
1107
1108     return rtn;
1109     }
1110
1111 /**
1112 \ingroup HighLevel_Sign
1113 \brief Sign a file
1114 \param input_filename Input filename
1115 \param output_filename Output filename. If NULL, a name is constructed from the input filename.
1116 \param skey Secret Key to use for signing
1117 \param use_armour Write armoured text, if set.
1118 \param overwrite May overwrite existing file, if set.
1119 \return ops_true if OK; else ops_false;
1120
1121 Example code:
1122 \code
1123 void example(const ops_secret_key_t *skey)
1124 {
1125   const char* filename="mytestfile";
1126   const ops_boolean_t use_armour=ops_false;
1127   const ops_boolean_t overwrite=ops_false;
1128   if (ops_sign_file(filename, NULL, skey, use_armour, overwrite)==ops_true)
1129     printf("OK");
1130   else
1131     printf("ERR"); 
1132 }
1133 \endcode
1134 */
1135 ops_boolean_t ops_sign_file(const char* input_filename,
1136                             const char* output_filename,
1137                             const ops_secret_key_t *skey,
1138                             const ops_boolean_t use_armour,
1139                             const ops_boolean_t overwrite)
1140     {
1141     // \todo allow choice of hash algorithams
1142     // enforce use of SHA1 for now
1143
1144     unsigned char keyid[OPS_KEY_ID_SIZE];
1145     ops_create_signature_t *sig=NULL;
1146
1147     int fd_out=0;
1148     ops_create_info_t *cinfo=NULL;
1149
1150     ops_hash_algorithm_t hash_alg=OPS_HASH_SHA1;
1151     ops_sig_type_t sig_type=OPS_SIG_BINARY;
1152
1153     ops_memory_t* mem_buf=NULL;
1154     ops_hash_t* hash=NULL;
1155
1156     // read input file into buf
1157
1158     int errnum;
1159     mem_buf=ops_write_mem_from_file(input_filename, &errnum);
1160     if (errnum)
1161         return ops_false;
1162
1163     // setup output file
1164
1165     fd_out=open_output_file(&cinfo, input_filename, output_filename, use_armour,
1166                             overwrite);
1167
1168     if (fd_out < 0)
1169         {
1170         ops_memory_free(mem_buf);
1171         return ops_false;
1172         }
1173
1174     // set up signature
1175     sig=ops_create_signature_new();
1176     ops_signature_start_message_signature(sig, skey, hash_alg, sig_type);
1177
1178     //  set armoured/not armoured here
1179     if (use_armour)
1180         ops_writer_push_armoured_message(cinfo);
1181
1182     if (debug)
1183         { fprintf(stderr, "** Writing out one pass sig\n"); }
1184
1185     // write one_pass_sig
1186     ops_write_one_pass_sig(skey, hash_alg, sig_type, cinfo);
1187
1188     // hash file contents
1189     hash=ops_signature_get_hash(sig);
1190     hash->add(hash, ops_memory_get_data(mem_buf),
1191               ops_memory_get_length(mem_buf));
1192    
1193     // output file contents as Literal Data packet
1194
1195     if (debug)
1196         fprintf(stderr,"** Writing out data now\n");
1197
1198     ops_write_literal_data_from_buf(ops_memory_get_data(mem_buf),
1199                                     ops_memory_get_length(mem_buf),
1200                                     OPS_LDT_BINARY, cinfo);
1201
1202     if (debug)
1203         fprintf(stderr, "** After Writing out data now\n");
1204
1205     // add subpackets to signature
1206     // - creation time
1207     // - key id
1208
1209     ops_signature_add_creation_time(sig, time(NULL));
1210
1211     ops_keyid(keyid, &skey->public_key);
1212     ops_signature_add_issuer_key_id(sig, keyid);
1213
1214     ops_signature_hashed_subpackets_end(sig);
1215
1216     // write out sig
1217     ops_write_signature(sig, &skey->public_key, skey, cinfo);
1218
1219     ops_teardown_file_write(cinfo, fd_out);
1220
1221     // tidy up
1222     ops_create_signature_delete(sig);
1223     ops_memory_free(mem_buf);
1224
1225     return ops_true;
1226     }
1227
1228 /**
1229 \ingroup HighLevel_Sign
1230 \brief Signs a buffer
1231 \param input Input text to be signed
1232 \param input_len Length of input text
1233 \param sig_type Signature type
1234 \param skey Secret Key
1235 \param use_armour Write armoured text, if set
1236 \param include_data Includes the signed data in the output message. If not, creates a detached signature.
1237 \return New ops_memory_t struct containing signed text
1238 \note It is the caller's responsibility to call ops_memory_free(me)
1239
1240 Example Code:
1241 \code
1242 void example(const ops_secret_key_t *skey)
1243 {
1244   const char* buf="Some example text";
1245   const size_t len=strlen(buf);
1246   const ops_boolean_t use_armour=ops_true;
1247
1248   ops_memory_t* mem=NULL;
1249  
1250   mem=ops_sign_buf(buf,len,OPS_SIG_BINARY,skey,use_armour);
1251   if (mem)
1252   {
1253     printf ("OK");
1254     ops_memory_free(mem);
1255   }
1256   else
1257   {
1258     printf("ERR");
1259   }
1260 }
1261 \endcode
1262 */
1263 ops_memory_t* ops_sign_buf(const void* input, const size_t input_len,
1264                            const ops_sig_type_t sig_type,
1265                            const ops_secret_key_t *skey,
1266                            const ops_boolean_t use_armour,
1267                            ops_boolean_t include_data)
1268     {
1269     // \todo allow choice of hash algorithams
1270     // enforce use of SHA1 for now
1271
1272     unsigned char keyid[OPS_KEY_ID_SIZE];
1273     ops_create_signature_t *sig=NULL;
1274
1275     ops_create_info_t *cinfo=NULL;
1276     ops_memory_t *mem=ops_memory_new();
1277
1278     ops_hash_algorithm_t hash_alg=OPS_HASH_SHA1;
1279     ops_literal_data_type_t ld_type;
1280     ops_hash_t* hash=NULL;
1281
1282     // setup literal data packet type
1283     if (sig_type == OPS_SIG_BINARY)
1284         ld_type=OPS_LDT_BINARY;
1285     else
1286         ld_type=OPS_LDT_TEXT;
1287
1288     // set up signature
1289     sig=ops_create_signature_new();
1290     ops_signature_start_message_signature(sig, skey, hash_alg, sig_type);
1291
1292     // setup writer
1293     ops_setup_memory_write(&cinfo, &mem, input_len);
1294
1295     //  set armoured/not armoured here
1296     if (use_armour)
1297         ops_writer_push_armoured_message(cinfo);
1298
1299     if (debug)
1300         fprintf(stderr, "** Writing out one pass sig\n");
1301
1302     // write one_pass_sig
1303     ops_write_one_pass_sig(skey, hash_alg, sig_type, cinfo);
1304
1305     // hash file contents
1306     hash=ops_signature_get_hash(sig);
1307     hash->add(hash, input, input_len);
1308    
1309     // output file contents as Literal Data packet
1310
1311     if (debug)
1312         fprintf(stderr,"** Writing out data now\n");
1313
1314     if(include_data)
1315         ops_write_literal_data_from_buf(input, input_len, ld_type, cinfo);
1316
1317     if (debug)
1318         fprintf(stderr,"** After Writing out data now\n");
1319
1320     // add subpackets to signature
1321     // - creation time
1322     // - key id
1323
1324     ops_signature_add_creation_time(sig, time(NULL));
1325
1326     ops_keyid(keyid, &skey->public_key);
1327     ops_signature_add_issuer_key_id(sig, keyid);
1328
1329     ops_signature_hashed_subpackets_end(sig);
1330
1331     // write out sig
1332     ops_write_signature(sig, &skey->public_key, skey, cinfo);
1333
1334     // tidy up
1335     ops_writer_close(cinfo);
1336          free(cinfo) ;
1337     ops_create_signature_delete(sig);
1338
1339     return mem;
1340     }
1341
1342 typedef struct {
1343   ops_create_signature_t *signature;
1344   const ops_secret_key_t *skey;
1345   ops_hash_algorithm_t hash_alg;
1346   ops_sig_type_t sig_type;
1347 } signature_arg_t;
1348
1349 static ops_boolean_t stream_signature_writer(const unsigned char *src,
1350                                              unsigned length,
1351                                              ops_error_t **errors,
1352                                              ops_writer_info_t *winfo)
1353     {
1354     signature_arg_t* arg = ops_writer_get_arg(winfo);
1355     // Add the input data to the hash. At the end, we will use the hash
1356     // to generate a signature packet.
1357     ops_hash_t* hash = ops_signature_get_hash(arg->signature);
1358     hash->add(hash, src, length);
1359
1360     return ops_stacked_write(src, length, errors, winfo);
1361     }
1362
1363 static ops_boolean_t stream_signature_write_trailer(ops_create_info_t *cinfo,
1364                                                     void *data)
1365     {
1366     signature_arg_t* arg = data;
1367     unsigned char keyid[OPS_KEY_ID_SIZE];
1368
1369     // add subpackets to signature
1370     // - creation time
1371     // - key id
1372     ops_signature_add_creation_time(arg->signature,time(NULL));
1373     ops_keyid(keyid, &arg->skey->public_key);
1374     ops_signature_add_issuer_key_id(arg->signature, keyid);
1375     ops_signature_hashed_subpackets_end(arg->signature);
1376
1377     // write out signature
1378     return ops_write_signature(arg->signature, &arg->skey->public_key,
1379                                arg->skey, cinfo);
1380     }
1381
1382 static void stream_signature_destroyer(ops_writer_info_t *winfo)
1383     {
1384     signature_arg_t* arg = ops_writer_get_arg(winfo);
1385     ops_create_signature_delete(arg->signature);
1386     free(arg);
1387     }
1388
1389 /**
1390 \ingroup Core_WritePackets
1391 \brief Pushes a signed writer onto the stack.
1392
1393 Data written will be encoded as a onepass signature packet, followed
1394 by a literal packet, followed by a signature packet. Once this writer
1395 has been added to the stack, cleartext can be written straight to the
1396 output, and it will be encoded as a literal packet and signed.
1397
1398 \param cinfo Write settings
1399 \param sig_type the type of input to be signed (text or binary)
1400 \param skey the key used to sign the stream.
1401 \return false if the initial onepass packet could not be created.
1402 */
1403 ops_boolean_t ops_writer_push_signed(ops_create_info_t *cinfo,
1404                                      const ops_sig_type_t sig_type,
1405                                      const ops_secret_key_t *skey)
1406     {
1407     // \todo allow choice of hash algorithams
1408     // enforce use of SHA1 for now
1409
1410     // Create arg to be used with this writer
1411     // Remember to free this in the destroyer
1412     signature_arg_t *signature_arg = ops_mallocz(sizeof *signature_arg);
1413     signature_arg->signature = ops_create_signature_new();
1414     signature_arg->hash_alg = OPS_HASH_SHA1;
1415     signature_arg->skey = skey;
1416     signature_arg->sig_type = sig_type;
1417     ops_signature_start_message_signature(signature_arg->signature,
1418                                           signature_arg->skey,
1419                                           signature_arg->hash_alg,
1420                                           signature_arg->sig_type);
1421
1422     if (!ops_write_one_pass_sig(signature_arg->skey,
1423                                 signature_arg->hash_alg,
1424                                 signature_arg->sig_type,
1425                                 cinfo))
1426         return ops_false;
1427
1428     ops_writer_push_partial_with_trailer(0, cinfo, OPS_PTAG_CT_LITERAL_DATA,
1429                                          write_literal_header, NULL,
1430                                          stream_signature_write_trailer,
1431                                          signature_arg);
1432     // And push writer on stack
1433     ops_writer_push(cinfo, stream_signature_writer, NULL,
1434                     stream_signature_destroyer,signature_arg);
1435     return ops_true;
1436     }
1437
1438 // EOF
1439
Note: See TracBrowser for help on using the browser.