Botan  1.11.4
get_pbe.cpp
Go to the documentation of this file.
1 /*
2 * PBE Retrieval
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7 
8 #include <botan/get_pbe.h>
9 #include <botan/oids.h>
10 #include <botan/scan_name.h>
11 #include <botan/parsing.h>
12 #include <botan/libstate.h>
13 
14 #if defined(BOTAN_HAS_PBE_PKCS_V15)
15  #include <botan/pbes1.h>
16 #endif
17 
18 #if defined(BOTAN_HAS_PBE_PKCS_V20)
19  #include <botan/pbes2.h>
20  #include <botan/hmac.h>
21 #endif
22 
23 namespace Botan {
24 
25 /*
26 * Get an encryption PBE, set new parameters
27 */
28 PBE* get_pbe(const std::string& algo_spec,
29  const std::string& passphrase,
30  std::chrono::milliseconds msec,
32  {
33  SCAN_Name request(algo_spec);
34 
35  const std::string pbe = request.algo_name();
36  std::string digest_name = request.arg(0);
37  const std::string cipher = request.arg(1);
38 
39  std::vector<std::string> cipher_spec = split_on(cipher, '/');
40  if(cipher_spec.size() != 2)
41  throw Invalid_Argument("PBE: Invalid cipher spec " + cipher);
42 
43  const std::string cipher_algo = global_state().deref_alias(cipher_spec[0]);
44  const std::string cipher_mode = cipher_spec[1];
45 
46  if(cipher_mode != "CBC")
47  throw Invalid_Argument("PBE: Invalid cipher mode " + cipher);
48 
50 
51  const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_algo);
52  if(!block_cipher)
53  throw Algorithm_Not_Found(cipher_algo);
54 
55  const HashFunction* hash_function = af.prototype_hash_function(digest_name);
56  if(!hash_function)
57  throw Algorithm_Not_Found(digest_name);
58 
59  if(request.arg_count() != 2)
60  throw Invalid_Algorithm_Name(algo_spec);
61 
62 #if defined(BOTAN_HAS_PBE_PKCS_V15)
63  if(pbe == "PBE-PKCS5v15")
64  return new PBE_PKCS5v15(block_cipher->clone(),
65  hash_function->clone(),
66  passphrase,
67  msec,
68  rng);
69 #endif
70 
71 #if defined(BOTAN_HAS_PBE_PKCS_V20)
72  if(pbe == "PBE-PKCS5v20")
73  return new PBE_PKCS5v20(block_cipher->clone(),
74  new HMAC(hash_function->clone()),
75  passphrase,
76  msec,
77  rng);
78 #endif
79 
80  throw Algorithm_Not_Found(algo_spec);
81  }
82 
83 /*
84 * Get a decryption PBE, decode parameters
85 */
86 PBE* get_pbe(const OID& pbe_oid,
87  const std::vector<byte>& params,
88  const std::string& passphrase)
89  {
90  SCAN_Name request(OIDS::lookup(pbe_oid));
91 
92  const std::string pbe = request.algo_name();
93 
94 #if defined(BOTAN_HAS_PBE_PKCS_V15)
95  if(pbe == "PBE-PKCS5v15")
96  {
97  if(request.arg_count() != 2)
98  throw Invalid_Algorithm_Name(request.as_string());
99 
100  std::string digest_name = request.arg(0);
101  const std::string cipher = request.arg(1);
102 
103  std::vector<std::string> cipher_spec = split_on(cipher, '/');
104  if(cipher_spec.size() != 2)
105  throw Invalid_Argument("PBE: Invalid cipher spec " + cipher);
106 
107  const std::string cipher_algo = global_state().deref_alias(cipher_spec[0]);
108  const std::string cipher_mode = cipher_spec[1];
109 
110  if(cipher_mode != "CBC")
111  throw Invalid_Argument("PBE: Invalid cipher mode " + cipher);
112 
114 
115  const BlockCipher* block_cipher = af.prototype_block_cipher(cipher_algo);
116  if(!block_cipher)
117  throw Algorithm_Not_Found(cipher_algo);
118 
119  const HashFunction* hash_function =
120  af.prototype_hash_function(digest_name);
121 
122  if(!hash_function)
123  throw Algorithm_Not_Found(digest_name);
124 
125  return new PBE_PKCS5v15(block_cipher->clone(),
126  hash_function->clone(),
127  params,
128  passphrase);
129  }
130 #endif
131 
132 #if defined(BOTAN_HAS_PBE_PKCS_V20)
133  if(pbe == "PBE-PKCS5v20")
134  return new PBE_PKCS5v20(params, passphrase);
135 #endif
136 
137  throw Algorithm_Not_Found(pbe_oid.as_string());
138  }
139 
140 }