1 /**
2 * EMSA/EME Retrieval
3 * 
4 * Copyright:
5 * (C) 1999-2007 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.pk_pad.factory;
12 
13 import botan.pk_pad.emsa;
14 import botan.pk_pad.eme;
15 import botan.libstate.libstate;
16 import botan.algo_base.scan_token;
17 import botan.utils.exceptn;
18 
19 import botan.constants;
20 static if (BOTAN_HAS_EMSA1)          import botan.pk_pad.emsa1;
21 static if (BOTAN_HAS_EMSA1_BSI)      import botan.pk_pad.emsa1_bsi;
22 static if (BOTAN_HAS_EMSA_X931)      import botan.pk_pad.emsa_x931;
23 static if (BOTAN_HAS_EMSA_PKCS1)     import botan.pk_pad.emsa_pkcs1;
24 static if (BOTAN_HAS_EMSA_PSSR)      import botan.pk_pad.pssr;
25 static if (BOTAN_HAS_EMSA_RAW)       import botan.pk_pad.emsa_raw;
26 static if (BOTAN_HAS_EME_OAEP)       import botan.pk_pad.oaep;
27 static if (BOTAN_HAS_EME_PKCS1_V15)  import botan.pk_pad.eme_pkcs;
28 
29 /**
30 * Factory method for EMSA (message-encoding methods for signatures
31 * with appendix) objects
32 * Params:
33 *  algo_spec = the name of the EME to create
34 * Returns: pointer to newly allocated object of that type
35 */
36 EMSA getEmsa(in string algo_spec)
37 {
38     SCANToken request = SCANToken(algo_spec);
39     
40     AlgorithmFactory af = globalState().algorithmFactory();
41     
42     static if (BOTAN_HAS_EMSA_RAW) {
43         if (request.algoName == "Raw" && request.argCount() == 0)
44             return new EMSARaw;
45     }
46     
47     if (request.algoName == "EMSA1" && request.argCount() == 1)
48     {
49         static if (BOTAN_HAS_EMSA_RAW) {
50             if (request.arg(0) == "Raw")
51                 return new EMSARaw;
52         }
53         
54         static if (BOTAN_HAS_EMSA1) {
55             return new EMSA1(af.makeHashFunction(request.arg(0)));
56         }
57     }
58     
59     static if (BOTAN_HAS_EMSA1_BSI) {
60         if (request.algoName == "EMSA1_BSI" && request.argCount() == 1)
61             return new EMSA1BSI(af.makeHashFunction(request.arg(0)));
62     }
63     
64     static if (BOTAN_HAS_EMSA_X931) {
65         if (request.algoName == "EMSA_X931" && request.argCount() == 1)
66             return new EMSAX931(af.makeHashFunction(request.arg(0)));
67     }
68     
69     static if (BOTAN_HAS_EMSA_PKCS1) {
70         if (request.algoName == "EMSA_PKCS1" && request.argCount() == 1)
71         {
72             if (request.arg(0) == "Raw")
73                 return new EMSAPKCS1v15Raw;
74             return new EMSAPKCS1v15(af.makeHashFunction(request.arg(0)));
75         }
76     }
77     
78     static if (BOTAN_HAS_EMSA_PSSR) {
79         if (request.algoName == "PSSR" && request.argCountBetween(1, 3))
80         {
81             // 3 args: Hash, MGF, salt size (MGF is hardcoded MGF1 in Botan)
82             if (request.argCount() == 1)
83                 return new PSSR(af.makeHashFunction(request.arg(0)));
84             
85             if (request.argCount() == 2 && request.arg(1) != "MGF1")
86                 return new PSSR(af.makeHashFunction(request.arg(0)));
87             
88             if (request.argCount() == 3)
89                 return new PSSR(af.makeHashFunction(request.arg(0)), request.argAsInteger(2, 0));
90         }
91     }
92     
93     throw new AlgorithmNotFound(algo_spec);
94 }
95 
96 /**
97 * Factory method for EME (message-encoding methods for encryption) objects
98 * Params:
99 *  algo_spec = the name of the EME to create
100 * Returns: pointer to newly allocated object of that type
101 */
102 EME getEme(in string algo_spec)
103 {
104     SCANToken request = SCANToken(algo_spec);
105     
106     if (request.algoName == "Raw")
107         return null; // No padding
108     
109     static if (BOTAN_HAS_EME_PKCS1_V15) {
110         if (request.algoName == "PKCS1v15" && request.argCount() == 0)
111             return new EMEPKCS1v15;
112     }
113     
114     static if (BOTAN_HAS_EME_OAEP) {
115         AlgorithmFactory af = globalState().algorithmFactory();
116         
117         if (request.algoName == "OAEP" && request.argCountBetween(1, 2))
118         {
119             if (request.argCount() == 1 ||
120                 (request.argCount() == 2 && request.arg(1) == "MGF1"))
121             {
122                 return new OAEP(af.makeHashFunction(request.arg(0)));
123             }
124         }
125     }
126     
127     throw new AlgorithmNotFound(algo_spec);
128 }