1 /**
2 * Public Key Interface
3 * 
4 * Copyright:
5 * (C) 1999-2010 Jack Lloyd
6 * (C) 2014-2015 Etienne Cimon
7 *
8 * License:
9 * Botan is released under the Simplified BSD License (see LICENSE.md)
10 */
11 module botan.pubkey.pubkey;
12 
13 import botan.constants;
14 static if (BOTAN_HAS_PUBLIC_KEY_CRYPTO):
15 
16 import botan.utils.types;
17 public import botan.pubkey.pk_keys;
18 public import botan.pubkey.pk_ops;
19 public import botan.algo_base.symkey;
20 public import botan.utils.types;
21 public import botan.rng.rng;
22 public import botan.pubkey.pkcs8;
23 public import botan.pubkey.algo.ec_group;
24 public import botan.pk_pad.emsa : EMSA;
25 import botan.pk_pad.eme;
26 import botan.pk_pad.emsa;
27 import botan.pk_pad.factory;
28 import botan.kdf.kdf;
29 import botan.asn1.der_enc;
30 import botan.asn1.ber_dec;
31 import botan.math.bigint.bigint;
32 import botan.utils.parsing;
33 import botan.libstate.libstate;
34 import botan.engine.engine;
35 import botan.utils.bit_ops;
36 import botan.utils.exceptn;
37 import botan.utils.mem_ops;
38 
39 alias SignatureFormat = bool;
40 /**
41 * The two types of signature format supported by Botan.
42 */
43 enum : SignatureFormat { IEEE_1363, DER_SEQUENCE }
44 
45 alias FaultProtection = bool;
46 /**
47 * Enum marking if protection against fault attacks should be used
48 */
49 enum : FaultProtection {
50     ENABLE_FAULT_PROTECTION,
51     DISABLE_FAULT_PROTECTION
52 }
53 
54 /**
55 * Public Key Encryptor
56 */
57 interface PKEncryptor
58 {
59 public:
60 
61     /**
62     * Encrypt a message.
63     *
64     * Params:
65     *  input = the message as a ubyte array
66     *  length = the length of the above ubyte array
67     *  rng = the random number source to use
68     * Returns: encrypted message
69     */
70     final Vector!ubyte encrypt(const(ubyte)* input, size_t length, RandomNumberGenerator rng) const
71     {
72         return enc(input, length, rng);
73     }
74 
75     /**
76     * Encrypt a message.
77     *
78     * Params:
79     *  input = the message
80     *  rng = the random number source to use
81     * Returns: encrypted message
82     */
83     final Vector!ubyte encrypt(Alloc)(const ref Vector!( ubyte, Alloc ) input, RandomNumberGenerator rng) const
84     {
85         return enc(input.ptr, input.length, rng);
86     }
87 
88     /**
89     * Return the maximum allowed message size in bytes.
90     * Returns: maximum message size in bytes
91     */
92     abstract size_t maximumInputSize() const;
93 
94 protected:
95     abstract Vector!ubyte enc(const(ubyte)*, size_t, RandomNumberGenerator) const;
96 }
97 
98 /**
99 * Public Key Decryptor
100 */
101 interface PKDecryptor
102 {
103 public:
104     /**
105     * Decrypt a ciphertext.
106     *
107     * Params:
108     *  input = the ciphertext as a ubyte array
109     *  length = the length of the above ubyte array
110     * Returns: decrypted message
111     */
112     final SecureVector!ubyte decrypt(const(ubyte)* input, size_t length) const
113     {
114         return dec(input, length);
115     }
116 
117     /**
118     * Decrypt a ciphertext.
119     *
120     * Params:
121     *  input = the ciphertext
122     * Returns: decrypted message
123     */
124     final SecureVector!ubyte decrypt(Alloc)(auto const ref Vector!( ubyte, Alloc ) input) const
125     {
126         return dec(input.ptr, input.length);
127     }
128 
129 protected:
130     abstract SecureVector!ubyte dec(const(ubyte)*, size_t) const;
131 }
132 
133 /**
134 * Public Key Signer. Use the signMessage() functions for small
135 * messages. Use multiple calls update() to process large messages and
136 * generate the signature by finally calling signature().
137 */
138 struct PKSigner
139 {
140 public:
141     /**
142     * Sign a message.
143     *
144     * Params:
145     *  msg = the message to sign as a ubyte array
146     *  length = the length of the above ubyte array
147     *  rng = the rng to use
148     * Returns: signature
149     */
150     Vector!ubyte signMessage(const(ubyte)* msg, size_t length, RandomNumberGenerator rng)
151     {
152         update(msg, length);
153         return signature(rng);
154     }
155 
156     /**
157     * Sign a message.
158     *
159     * Params:
160     *  input = the message to sign
161     *  rng = the rng to use
162     * Returns: signature
163     */
164     Vector!ubyte signMessage(ALLOC)(auto const ref Vector!(ubyte, ALLOC) input, RandomNumberGenerator rng)
165     { return signMessage(input.ptr, input.length, rng); }
166 
167     Vector!ubyte signMessage(ALLOC)(auto const ref RefCounted!(Vector!(ubyte, ALLOC), ALLOC) input, RandomNumberGenerator rng)
168     { return signMessage(input.ptr, input.length, rng); }
169 
170     /**
171     * Add a message part (single ubyte).
172     *
173     * Params:
174     *  input = the ubyte to add
175     */
176     void update(ubyte input) { update(&input, 1); }
177 
178     /**
179     * Add a message part.
180     *
181     * Params:
182     *  input = the message part to add as a ubyte array
183     *  length = the length of the above ubyte array
184     */
185     void update(const(ubyte)* input, size_t length)
186     {
187         m_emsa.update(input, length);
188     }
189 
190     /**
191     * Add a message part.
192     *
193     * Params:
194     *  input = the message part to add
195     */
196     void update(ALLOC)(auto const ref RefCounted!(Vector!(ubyte, ALLOC), ALLOC) input) { update(input.ptr, input.length); }
197     void update(ALLOC)(auto const ref Vector!(ubyte, ALLOC) input) { update(input.ptr, input.length); }
198 
199     /**
200     * Get the signature of the so far processed message (provided by the
201     * calls to update()).
202     *
203     * Params:
204     *  rng = the rng to use
205     * Returns: signature of the total message
206     */
207     Vector!ubyte signature(RandomNumberGenerator rng)
208     {
209         Vector!ubyte encoded = unlock(m_emsa.encodingOf(m_emsa.rawData(), m_op.maxInputBits(), rng));
210         Vector!ubyte plain_sig = unlock(m_op.sign(encoded.ptr, encoded.length, rng));
211         
212         assert(selfTestSignature(encoded, plain_sig), "Signature was consistent");
213         
214         if (m_op.messageParts() == 1 || m_sig_format == IEEE_1363)
215             return plain_sig.move();
216         
217         if (m_sig_format == DER_SEQUENCE)
218         {
219             if (plain_sig.length % m_op.messageParts())
220                 throw new EncodingError("PKSigner: strange signature size found");
221             const size_t SIZE_OF_PART = plain_sig.length / m_op.messageParts();
222 
223             Vector!(RefCounted!BigInt) sig_parts = Vector!(RefCounted!BigInt)(m_op.messageParts());
224             for (size_t j = 0; j != sig_parts.length; ++j)
225                 sig_parts[j].binaryDecode(&plain_sig[SIZE_OF_PART*j], SIZE_OF_PART);
226             
227             return DEREncoder()
228                     .startCons(ASN1Tag.SEQUENCE)
229                     .encodeList(sig_parts)
230                     .endCons()
231                     .getContentsUnlocked();
232         }
233         else
234             throw new EncodingError("PKSigner: Unknown signature format " ~ to!string(m_sig_format));
235     }
236 
237     /**
238     * Set the output format of the signature.
239     *
240     * Params:
241     *  format = the signature format to use
242     */
243     void setOutputFormat(SignatureFormat format) { m_sig_format = format; }
244 
245     /**
246     * Construct a PK Signer.
247     *
248     * Params:
249     *  key = the key to use inside this signer
250     *  emsa_name = the EMSA to use, e.g. "EMSA1(SHA-224)".
251     *  format = the signature format to use
252     *  prot = says if fault protection should be enabled
253     */
254     this(in PrivateKey key, in string emsa_name,
255          SignatureFormat format = IEEE_1363,
256          FaultProtection prot = DISABLE_FAULT_PROTECTION)
257     {
258         AlgorithmFactory af = globalState().algorithmFactory();
259 
260         RandomNumberGenerator rng = globalState().globalRng();
261         
262         foreach (Engine engine; af.engines[]) {
263             if (!m_op)
264                 m_op = engine.getSignatureOp(key, rng);
265             if (!m_verify_op && prot == ENABLE_FAULT_PROTECTION)
266                 m_verify_op = engine.getVerifyOp(key, rng);
267             if (m_op && (m_verify_op || prot == DISABLE_FAULT_PROTECTION))
268                 break;
269         }
270 		scope(failure) { m_op.free(); m_verify_op.free(); }
271         
272         if (!m_op || (!m_verify_op && prot == ENABLE_FAULT_PROTECTION))
273             throw new LookupError("Signing with " ~ key.algoName ~ " not supported");
274         
275         m_emsa = getEmsa(emsa_name);
276         m_sig_format = format;
277     }
278 private:
279     /*
280     * Check the signature we just created, to help prevent fault attacks
281     */
282     bool selfTestSignature()(auto const ref Vector!ubyte msg, auto const ref Vector!ubyte sig) const
283     {
284         if (!m_verify_op)
285             return true; // checking disabled, assume ok
286         
287         if (m_verify_op.withRecovery())
288         {
289             Vector!ubyte recovered = unlock((cast(Verification)*m_verify_op).verifyMr(sig.ptr, sig.length));
290             
291             if (msg.length > recovered.length)
292             {
293                 size_t extra_0s = msg.length - recovered.length;
294                 
295                 foreach (size_t i; 0 .. extra_0s)
296                     if (msg[i] != 0)
297                         return false;
298                 
299                 return sameMem(&msg[extra_0s], recovered.ptr, recovered.length);
300             }
301             
302             return (recovered == msg);
303         }
304         else
305             return (cast(Verification)*m_verify_op).verify(msg.ptr, msg.length, sig.ptr, sig.length);
306     }
307 
308     Unique!Signature m_op;
309     Unique!Verification m_verify_op;
310     Unique!EMSA m_emsa;
311     SignatureFormat m_sig_format;
312 }
313 
314 /**
315 * Public Key Verifier. Use the verifyMessage() functions for small
316 * messages. Use multiple calls update() to process large messages and
317 * verify the signature by finally calling checkSignature().
318 */
319 struct PKVerifier
320 {
321 public:
322     /**
323     * Verify a signature.
324     *
325     * Params:
326     *  msg = the message that the signature belongs to, as a ubyte array
327     *  msg_length = the length of the above ubyte array msg
328     *  sig = the signature as a ubyte array
329     *  sig_length = the length of the above ubyte array sig
330     * Returns: true if the signature is valid
331     */
332     bool verifyMessage(const(ubyte)* msg, size_t msg_length,
333                        const(ubyte)* sig, size_t sig_length)
334     {
335         update(msg, msg_length);
336         //logTrace("Done update");
337         return checkSignature(sig, sig_length);
338     }
339 
340     /**
341     * Verify a signature.
342     *
343     * Params:
344     *  msg = the message that the signature belongs to
345     *  sig = the signature
346     * Returns: true if the signature is valid
347     */
348     bool verifyMessage(Alloc, Alloc2)(auto const ref Vector!( ubyte, Alloc ) msg, 
349                                       auto const ref Vector!( ubyte, Alloc2 ) sig)
350     {
351         return verifyMessage(msg.ptr, msg.length, sig.ptr, sig.length);
352     }
353 
354     /// ditto
355     bool verifyMessage(Alloc, Alloc2)(auto const ref RefCounted!(Vector!( ubyte, Alloc ), Alloc) msg, 
356                                       auto const ref RefCounted!(Vector!( ubyte, Alloc2 ), Alloc2) sig)
357     {
358         return verifyMessage(msg.ptr, msg.length, sig.ptr, sig.length);
359     }
360 
361     /**
362     * Add a message part (single ubyte) of the message corresponding to the
363     * signature to be verified.
364     *
365     * Params:
366     *  input = the ubyte to add
367     */
368     void update(ubyte input) { update(&input, 1); }
369 
370     /**
371     * Add a message part of the message corresponding to the
372     * signature to be verified.
373     *
374     * Params:
375     *  input = the new message part as a ubyte array
376     *  length = the length of the above ubyte array
377     */
378     void update(const(ubyte)* input, size_t length)
379     {
380         m_emsa.update(input, length);
381     }
382 
383     /**
384     * Add a message part of the message corresponding to the
385     * signature to be verified.
386     *
387     * Params:
388     *  input = the new message part
389     */
390     void update(const ref Vector!ubyte input)
391     { update(input.ptr, input.length); }
392 
393     /**
394     * Check the signature of the buffered message, i.e. the one build
395     * by successive calls to update.
396     *
397     * Params:
398     *  sig = the signature to be verified as a ubyte array
399     *  length = the length of the above ubyte array
400     * Returns: true if the signature is valid, false otherwise
401     */
402     bool checkSignature(const(ubyte)* sig, size_t length)
403     {
404         try {
405             if (m_sig_format == IEEE_1363)
406                 return validateSignature(m_emsa.rawData(), sig, length);
407             else if (m_sig_format == DER_SEQUENCE)
408             {
409                 BERDecoder decoder = BERDecoder(sig, length);
410                 BERDecoder ber_sig = decoder.startCons(ASN1Tag.SEQUENCE);
411                 
412                 size_t count = 0;
413                 SecureVector!ubyte real_sig;
414                 while (ber_sig.moreItems())
415                 {
416                     BigInt sig_part;
417                     ber_sig.decode(sig_part);
418                     real_sig ~= BigInt.encode1363(sig_part, m_op.messagePartSize());
419                     ++count;
420                 }
421                 
422                 if (count != m_op.messageParts())
423                     throw new DecodingError("PKVerifier: signature size invalid");
424                 
425                 return validateSignature(m_emsa.rawData(), real_sig.ptr, real_sig.length);
426             }
427             else
428                 throw new DecodingError("PKVerifier: Unknown signature format " ~ to!string(m_sig_format));
429         }
430         catch(InvalidArgument) { return false; }
431     }
432 
433     /**
434     * Check the signature of the buffered message, i.e. the one build
435     * by successive calls to update.
436     *
437     * Params:
438     *  sig = the signature to be verified
439     * Returns: true if the signature is valid, false otherwise
440     */
441     bool checkSignature(Alloc)(auto const ref Vector!( ubyte, Alloc ) sig)
442     {
443         return checkSignature(sig.ptr, sig.length);
444     }
445 
446     /**
447     * Set the format of the signatures fed to this verifier.
448     *
449     * Params:
450     *  format = the signature format to use
451     */
452     void setInputFormat(SignatureFormat format)
453     {
454         if (m_op.messageParts() == 1 && format != IEEE_1363)
455             throw new InvalidState("PKVerifier: This algorithm always uses IEEE 1363");
456         m_sig_format = format;
457     }
458 
459     /**
460     * Construct a PK Verifier.
461     *
462     * Params:
463     *  key = the public key to verify against
464     *  emsa_name = the EMSA to use (eg "EMSA3(SHA-1)")
465     *  format = the signature format to use
466     */
467     this(in PublicKey key, in string emsa_name, SignatureFormat format = IEEE_1363)
468     {
469         AlgorithmFactory af = globalState().algorithmFactory();
470         RandomNumberGenerator rng = globalState().globalRng();
471 
472         foreach (Engine engine; af.engines[]) {
473             m_op = engine.getVerifyOp(key, rng);
474             if (m_op)
475                 break;
476         }
477 		scope(failure) m_op.free();
478         if (!m_op)
479             throw new LookupError("Verification with " ~ key.algoName ~ " not supported");
480         m_emsa = getEmsa(emsa_name);
481         m_sig_format = format;
482     }
483 
484 private:
485     bool validateSignature()(auto const ref SecureVector!ubyte msg, const(ubyte)* sig, size_t sig_len)
486     {
487         if (m_op.withRecovery())
488         {
489             SecureVector!ubyte output_of_key = m_op.verifyMr(sig, sig_len);
490             return m_emsa.verify(output_of_key, msg, m_op.maxInputBits());
491         }
492         else
493         {
494             RandomNumberGenerator rng = globalState().globalRng();
495             
496             SecureVector!ubyte encoded = m_emsa.encodingOf(msg, m_op.maxInputBits(), rng);
497             
498             return m_op.verify(encoded.ptr, encoded.length, sig, sig_len);
499         }
500     }
501 
502     Unique!Verification m_op;
503     Unique!EMSA m_emsa;
504     SignatureFormat m_sig_format;
505 }
506 
507 /**
508 * Key used for key agreement
509 */
510 class PKKeyAgreement
511 {
512 public:
513 
514     /*
515     * Perform Key Agreement Operation
516     * Params:
517     *  key_len = the desired key output size
518     *  input = the other parties key
519     *  in_len = the length of in in bytes
520     *  params = extra derivation params
521     *  params_len = the length of params in bytes
522     */
523     SymmetricKey deriveKey(size_t key_len, const(ubyte)* input,
524                            size_t in_len, const(ubyte)* params,
525                            size_t params_len) const
526     {
527         SecureVector!ubyte z = (cast(KeyAgreement)*m_op).agree(input, in_len);
528 
529         if (!m_kdf)
530             return SymmetricKey(z);
531         
532         return SymmetricKey(m_kdf.deriveKey(key_len, z, params, params_len));
533     }
534 
535     /*
536     * Perform Key Agreement Operation
537     * Params:
538     *  key_len = the desired key output size
539     *  input = the other parties key
540     *  in_len = the length of in in bytes
541     *  params = extra derivation params
542     *  params_len = the length of params in bytes
543     */
544     SymmetricKey deriveKey()(size_t key_len, auto const ref Vector!ubyte input, 
545                              const(ubyte)* params, size_t params_len) const
546     {
547         return deriveKey(key_len, input.ptr, input.length, params, params_len);
548     }
549 
550     /*
551     * Perform Key Agreement Operation
552     * Params:
553     *  key_len = the desired key output size
554     *  input = the other parties key
555     *  in_len = the length of in in bytes
556     *  params = extra derivation params
557     */
558     SymmetricKey deriveKey(size_t key_len, const(ubyte)* input, size_t in_len, in string params = "") const
559     {
560         return deriveKey(key_len, input, in_len, cast(const(ubyte)*)(params.ptr), params.length);
561     }
562 
563     /*
564     * Perform Key Agreement Operation
565     * Params:
566     *  key_len = the desired key output size
567     *  input = the other parties key
568     *  params = extra derivation params
569     */
570     SymmetricKey deriveKey()(size_t key_len,
571                              auto const ref Vector!ubyte input,
572                              in string params = "") const
573     {
574         return deriveKey(key_len, input.ptr, input.length,
575                                 cast(const(ubyte)*)(params.ptr),
576                                 params.length);
577     }
578 
579     /**
580     * Construct a PK Key Agreement.
581     *
582     * Params:
583     *  key = the key to use
584     *  kdf_name = name of the KDF to use (or 'Raw' for no KDF)
585     */
586     this(in PKKeyAgreementKey key, in string kdf_name)
587     {
588         AlgorithmFactory af = globalState().algorithmFactory();
589         RandomNumberGenerator rng = globalState().globalRng();
590 
591         foreach (Engine engine; af.engines[])
592         {
593             m_op = engine.getKeyAgreementOp(key, rng);
594             if (m_op)
595                 break;
596         }
597         
598         if (!m_op)
599             throw new LookupError("Key agreement with " ~ key.algoName ~ " not supported");
600         
601         m_kdf = getKdf(kdf_name);
602     }
603 private:
604     Unique!KeyAgreement m_op;
605     Unique!KDF m_kdf;
606 }
607 
608 /**
609 * Encryption with an MR algorithm and an EME.
610 */
611 class PKEncryptorEME : PKEncryptor
612 {
613 public:
614     /*
615     * Return the max size, in bytes, of a message
616     */
617     override size_t maximumInputSize() const
618     {
619         if (!m_eme)
620             return (m_op.maxInputBits() / 8);
621         else
622             return m_eme.maximumInputSize(m_op.maxInputBits());
623     }
624 
625     /**
626     * Construct an instance.
627     *
628     * Params:
629     *  key = the key to use inside the decryptor
630     *  eme_name = the EME to use
631     */
632     this(in PublicKey key, in string eme_name)
633     {
634         
635         AlgorithmFactory af = globalState().algorithmFactory();
636         RandomNumberGenerator rng = globalState().globalRng();
637 
638         foreach (Engine engine; af.engines[]) {
639             m_op = engine.getEncryptionOp(key, rng);
640             if (m_op)
641                 break;
642         }
643         
644         if (!m_op)
645             throw new LookupError("Encryption with " ~ key.algoName ~ " not supported");
646         
647         m_eme = getEme(eme_name);
648     }
649 
650 protected:
651     override Vector!ubyte enc(const(ubyte)* input, size_t length, RandomNumberGenerator rng) const
652     {
653         if (m_eme)
654         {
655             SecureVector!ubyte encoded = m_eme.encode(input, length, m_op.maxInputBits(), rng);
656             
657             if (8*(encoded.length - 1) + highBit(encoded[0]) > m_op.maxInputBits())
658                 throw new InvalidArgument("PKEncryptorEME: Input is too large");
659             
660             return unlock((cast(Encryption)*m_op).encrypt(encoded.ptr, encoded.length, rng));
661         }
662         else
663         {
664             if (8*(length - 1) + highBit(input[0]) > m_op.maxInputBits())
665                 throw new InvalidArgument("PKEncryptorEME: Input is too large");
666             
667             return unlock((cast(Encryption)*m_op).encrypt(input, length, rng));
668         }
669     }
670 
671 private:
672     Unique!Encryption m_op;
673     Unique!EME m_eme;
674 }
675 
676 /**
677 * Decryption with an MR algorithm and an EME.
678 */
679 class PKDecryptorEME : PKDecryptor
680 {
681 public:
682   /**
683     * Construct an instance.
684     *
685     * Params:
686     *  key = the key to use inside the encryptor
687     *  eme_name = the EME to use
688     */
689     this(in PrivateKey key, in string eme_name)
690     {
691         AlgorithmFactory af = globalState().algorithmFactory();
692         RandomNumberGenerator rng = globalState().globalRng();
693 
694         foreach (Engine engine; af.engines[])
695         {
696             m_op = engine.getDecryptionOp(key, rng);
697             if (m_op)
698                 break;
699         }
700         
701         if (!m_op)
702             throw new LookupError("Decryption with " ~ key.algoName ~ " not supported");
703         
704         m_eme = getEme(eme_name);
705     }
706 
707 protected:
708     /*
709     * Decrypt a message
710     */
711     override SecureVector!ubyte dec(const(ubyte)* msg, size_t length) const
712     {
713         try {
714             SecureVector!ubyte decrypted = (cast(Decryption)*m_op).decrypt(msg, length);
715             if (m_eme)
716                 return m_eme.decode(decrypted, m_op.maxInputBits());
717             else
718                 return decrypted.move();
719         }
720         catch(InvalidArgument)
721         {
722             throw new DecodingError("PKDecryptorEME: Input is invalid");
723         }
724     }
725    
726 private:
727     Unique!Decryption m_op;
728     Unique!EME m_eme;
729 }