Source code of Windows XP (NT5)
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.

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