Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

276 lines
7.3 KiB

  1. // RsaKPGen.cpp -- Rsa Key Pair Generator class definition
  2. // (c) Copyright Schlumberger Technology Corp., unpublished work, created
  3. // 1999. This computer program includes Confidential, Proprietary
  4. // Information and is a Trade Secret of Schlumberger Technology Corp. All
  5. // use, disclosure, and/or reproduction is prohibited unless authorized
  6. // in writing. All Rights Reserved.
  7. #include "NoWarning.h"
  8. #include "ForceLib.h"
  9. #include <limits>
  10. #include <windows.h>
  11. #include <wincrypt.h>
  12. #include <scuOsExc.h>
  13. #include <scuArrayP.h>
  14. #include <iopPriBlob.h>
  15. #include "RsaKPGen.h"
  16. #include "Blob.h"
  17. #include "AuxContext.h"
  18. #include "MsRsaPriKB.h"
  19. #include "PublicKeyHelper.h"
  20. using namespace std;
  21. using namespace cci;
  22. using namespace scu;
  23. /////////////////////////// LOCAL/HELPER /////////////////////////////////
  24. namespace
  25. {
  26. KeyType
  27. AsKeyType(RsaKey::StrengthType st)
  28. {
  29. KeyType kt;
  30. switch (st)
  31. {
  32. case 512:
  33. kt = ktRSA512;
  34. break;
  35. case 768:
  36. kt = ktRSA768;
  37. break;
  38. case 1024:
  39. kt = ktRSA1024;
  40. break;
  41. default:
  42. throw scu::OsException(ERROR_INVALID_PARAMETER);
  43. break;
  44. }
  45. return kt;
  46. }
  47. DWORD
  48. DefaultPublicExponent()
  49. {
  50. return 0x00010001; // same as Microsoft providers
  51. }
  52. pair<CPrivateKey, CPublicKey>
  53. KeyPair(CPrivateKey const &rhprikey,
  54. Blob const &rblbOrigModulus, // little endian
  55. Blob const &rblbOrigExponent) // little endian
  56. {
  57. CPublicKey hpubkey(AsPublicKey(rblbOrigModulus,
  58. rblbOrigExponent,
  59. rhprikey->Card()));
  60. return pair<CPrivateKey, CPublicKey>(rhprikey, hpubkey);
  61. }
  62. void
  63. ValidateCard(CCard const &rhcard)
  64. {
  65. if (!rhcard)
  66. throw scu::OsException(ERROR_INVALID_PARAMETER);
  67. }
  68. void
  69. ValidateStrength(RsaKey::StrengthType strength)
  70. {
  71. if (!IsValidRsaKeyStrength(strength))
  72. throw scu::OsException(ERROR_INVALID_PARAMETER);
  73. }
  74. bool
  75. IsEmpty(std::pair<CPrivateKey, CPublicKey> const &rhs)
  76. {
  77. return !rhs.first || !rhs.second;
  78. }
  79. }
  80. /////////////////////////// PUBLIC /////////////////////////////////
  81. // Types
  82. // C'tors/D'tors
  83. RsaKeyPairGenerator::RsaKeyPairGenerator(CCard const &rhcard,
  84. RsaKey::StrengthType strength)
  85. : m_hcard(rhcard),
  86. m_kp(),
  87. m_strength(strength)
  88. {
  89. ValidateParameters();
  90. }
  91. RsaKeyPairGenerator::~RsaKeyPairGenerator()
  92. {}
  93. // Operators
  94. pair<CPrivateKey, CPublicKey>
  95. RsaKeyPairGenerator::operator()() const
  96. {
  97. if (IsEmpty(m_kp))
  98. Generate();
  99. return m_kp;
  100. }
  101. // Operations
  102. void
  103. RsaKeyPairGenerator::Card(CCard const &rhcard)
  104. {
  105. if (m_hcard != rhcard)
  106. {
  107. ValidateCard(rhcard);
  108. Reset();
  109. m_hcard = rhcard;
  110. }
  111. }
  112. void
  113. RsaKeyPairGenerator::Reset()
  114. {
  115. m_kp = pair<CPrivateKey, CPublicKey>();
  116. }
  117. void
  118. RsaKeyPairGenerator::Strength(RsaKey::StrengthType strength)
  119. {
  120. if (m_strength != strength)
  121. {
  122. ValidateStrength(strength);
  123. Reset();
  124. m_strength = strength;
  125. }
  126. }
  127. // Access
  128. CCard
  129. RsaKeyPairGenerator::Card() const
  130. {
  131. return m_hcard;
  132. }
  133. bool
  134. RsaKeyPairGenerator::OnCard() const
  135. {
  136. return m_hcard->SupportedKeyFunction(AsKeyType(m_strength),
  137. coKeyGeneration);
  138. }
  139. RsaKey::StrengthType
  140. RsaKeyPairGenerator::Strength() const
  141. {
  142. return m_strength;
  143. }
  144. // Predicates
  145. // Static Variables
  146. /////////////////////////// PROTECTED /////////////////////////////////
  147. // C'tors/D'tors
  148. // Operators
  149. // Operations
  150. // Access
  151. // Predicates
  152. // Static Variables
  153. /////////////////////////// PRIVATE /////////////////////////////////
  154. // C'tors/D'tors
  155. // Operators
  156. // Operations
  157. void
  158. RsaKeyPairGenerator::Generate() const
  159. {
  160. KeyType kt = AsKeyType(m_strength);
  161. m_kp = OnCard()
  162. ? GenerateOnCard(kt)
  163. : GenerateInSoftware();
  164. }
  165. pair<CPrivateKey, CPublicKey>
  166. RsaKeyPairGenerator::GenerateInSoftware() const
  167. {
  168. AuxContext auxcontext;
  169. DWORD dwFlags;
  170. // strength (bit length) is the high-order word
  171. dwFlags = m_strength;
  172. dwFlags = dwFlags << (numeric_limits<DWORD>::digits / 2);
  173. dwFlags |= CRYPT_EXPORTABLE;
  174. HCRYPTKEY hcryptkey;
  175. if (!CryptGenKey(auxcontext(), AT_SIGNATURE, dwFlags, &hcryptkey))
  176. throw scu::OsException(GetLastError());
  177. DWORD dwDataLength;
  178. if (!CryptExportKey(hcryptkey, NULL, PRIVATEKEYBLOB, 0, 0, &dwDataLength))
  179. throw scu::OsException(GetLastError());
  180. SecureArray<BYTE> apbData(dwDataLength);
  181. if (!CryptExportKey(hcryptkey, NULL, PRIVATEKEYBLOB, 0, apbData.data(),
  182. &dwDataLength))
  183. throw scu::OsException(GetLastError());
  184. MsRsaPrivateKeyBlob msprivatekeyblob(apbData.data(), dwDataLength);
  185. if (msprivatekeyblob.BitLength() != m_strength)
  186. throw scu::OsException(NTE_BAD_LEN);
  187. CPrivateKey hprikey(m_hcard);
  188. hprikey->Value(*(AsPCciPrivateKeyBlob(msprivatekeyblob).get()));
  189. Blob blbModulus(msprivatekeyblob.Modulus(), msprivatekeyblob.Length());
  190. MsRsaPrivateKeyBlob::PublicExponentType pet = msprivatekeyblob.PublicExponent();
  191. Blob blbExponent(reinterpret_cast<Blob::value_type const *>(&pet), sizeof pet);
  192. return KeyPair(hprikey, blbModulus, blbExponent);
  193. }
  194. pair<CPrivateKey, CPublicKey>
  195. RsaKeyPairGenerator::GenerateOnCard(KeyType kt) const
  196. {
  197. DWORD dwExponent = DefaultPublicExponent();
  198. Blob blbExponent(reinterpret_cast<Blob::value_type const *>(&dwExponent),
  199. sizeof dwExponent);
  200. pair<string, CPrivateKey>
  201. ModulusKeyPair(m_hcard->GenerateKeyPair(kt,
  202. AsString(blbExponent)));
  203. CPrivateKey hprikey(ModulusKeyPair.second);
  204. Blob blbModulus(AsBlob(ModulusKeyPair.first));
  205. return KeyPair(hprikey, blbModulus, blbExponent);
  206. }
  207. void
  208. RsaKeyPairGenerator::ValidateParameters() const
  209. {
  210. ValidateCard(m_hcard);
  211. ValidateStrength(m_strength);
  212. }
  213. // Access
  214. // Predicates
  215. // Static Variables