blob: 3f14f43ed7348fb5ebbc289beba73d157e5127a2 [file] [log] [blame]
Jeff Thompson2747dc02013-10-04 19:11:34 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
5 * See COPYING for copyright and distribution information.
6 */
7
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -08008#include "common.hpp"
9
Alexander Afanasyev19508852014-01-29 01:01:51 -080010#include "sec-tpm-osx.hpp"
11
12#include "security/public-key.hpp"
13#include "util/logging.hpp"
Jeff Thompson2747dc02013-10-04 19:11:34 -070014
Yingdi Yu2b2b4792014-02-04 16:27:07 -080015#include <pwd.h>
16#include <unistd.h>
17#include <stdlib.h>
18#include <string.h>
Jeff Thompson2747dc02013-10-04 19:11:34 -070019
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080020#include <CoreFoundation/CoreFoundation.h>
21#include <Security/Security.h>
Yingdi Yu4b752752014-02-18 12:24:03 -080022#include <Security/SecRandom.h>
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080023#include <CoreServices/CoreServices.h>
Jeff Thompson2747dc02013-10-04 19:11:34 -070024
25using namespace std;
Jeff Thompson2747dc02013-10-04 19:11:34 -070026
Yingdi Yu87581582014-01-14 14:28:39 -080027INIT_LOGGER("SecTpmOsx");
Jeff Thompson2747dc02013-10-04 19:11:34 -070028
29namespace ndn
30{
Yingdi Yu2b2b4792014-02-04 16:27:07 -080031class SecTpmOsx::Impl {
32public:
33 Impl()
34 {}
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080035
Yingdi Yu2b2b4792014-02-04 16:27:07 -080036 /**
37 * @brief Convert NDN name of a key to internal name of the key.
38 *
39 * @param keyName the NDN name of the key
40 * @param keyClass the class of the key
41 * @return the internal key name
42 */
43 std::string
44 toInternalKeyName(const Name & keyName, KeyClass keyClass);
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080045
Yingdi Yu2b2b4792014-02-04 16:27:07 -080046 /**
47 * @brief Get key.
48 * @param keyName the name of the key
49 * @param keyClass the class of the key
50 * @returns pointer to the key
51 */
52 SecKeychainItemRef
53 getKey(const Name & keyName, KeyClass keyClass);
Alexander Afanasyev04b22a92014-01-05 22:40:17 -080054
Yingdi Yu2b2b4792014-02-04 16:27:07 -080055 /**
56 * convert keyType to MAC OS symmetric key key type
57 * @param keyType
58 * @returns MAC OS key type
59 */
Yingdi Yu87581582014-01-14 14:28:39 -080060 const CFTypeRef
Yingdi Yu2b2b4792014-02-04 16:27:07 -080061 getSymKeyType(KeyType keyType);
62
63 /**
64 * convert keyType to MAC OS asymmetirc key type
65 * @param keyType
66 * @returns MAC OS key type
67 */
Yingdi Yu87581582014-01-14 14:28:39 -080068 const CFTypeRef
Yingdi Yu2b2b4792014-02-04 16:27:07 -080069 getAsymKeyType(KeyType keyType);
70
71 /**
72 * convert keyClass to MAC OS key class
73 * @param keyClass
74 * @returns MAC OS key class
75 */
Yingdi Yu87581582014-01-14 14:28:39 -080076 const CFTypeRef
Yingdi Yu2b2b4792014-02-04 16:27:07 -080077 getKeyClass(KeyClass keyClass);
78
79 /**
80 * convert digestAlgo to MAC OS algorithm id
81 * @param digestAlgo
82 * @returns MAC OS algorithm id
83 */
Yingdi Yu87581582014-01-14 14:28:39 -080084 const CFStringRef
Yingdi Yu2b2b4792014-02-04 16:27:07 -080085 getDigestAlgorithm(DigestAlgorithm digestAlgo);
86
87 /**
88 * get the digest size of the corresponding algorithm
89 * @param digestAlgo the digest algorithm
90 * @return digest size
91 */
92 long
93 getDigestSize(DigestAlgorithm digestAlgo);
94
95 bool
96 getPassWord(string& password, string target);
97
98 ///////////////////////////////////////////////
99 // everything here is public, including data //
100 ///////////////////////////////////////////////
101public:
102 SecKeychainRef m_keyChainRef;
103};
104
105
106SecTpmOsx::SecTpmOsx()
107 : m_impl(new Impl)
108{
109 OSStatus res = SecKeychainCopyDefault(&m_impl->m_keyChainRef);
110
111
112 if (res == errSecNoDefaultKeychain) //If no default key chain, create one.
113 {
114 //Get the password for the new key chain.
115 string keyChainName("ndnroot.keychain");
116 cerr << "No Default KeyChain! Create " << keyChainName << ":" << endl;
117 string password;
118 while(!m_impl->getPassWord(password, keyChainName))
119 {
120 cerr << "Password mismatch!" << endl;
121 }
122
123 //Create the key chain
124 res = SecKeychainCreate(keyChainName.c_str(), //Keychain path
125 password.size(), //Keychain password length
126 password.c_str(), //Keychain password
127 false, //User prompt
128 NULL, //Initial access of Keychain
129 &m_impl->m_keyChainRef); //Keychain reference
130
131 if(res == errSecSuccess)
132 cerr << keyChainName << " has been created!" << endl;
133 else
134 {
135 char* pw = const_cast<char*>(password.c_str());
136 memset(pw, 0, password.size());
137 throw Error("No default keychain!");
138 }
139
140 //Unlock the default key chain
141 SecKeychainUnlock(m_impl->m_keyChainRef,
142 password.size(),
143 password.c_str(),
144 true);
145
146 char* pw = const_cast<char*>(password.c_str());
147 memset(pw, 0, password.size());
148
149 return;
150 }
151
152 //If the default key chain exists, check if it is unlocked
153 SecKeychainStatus keychainStatus;
154 res = SecKeychainGetStatus(m_impl->m_keyChainRef, &keychainStatus);
155 if(kSecUnlockStateStatus & keychainStatus)
156 return;
157
158
159 //If the default key chain is locked, unlock the key chain
160 bool locked = true;
161 while(locked)
162 {
163 const char* fmt = "Password to unlock the default keychain: ";
164 char* password = NULL;
165 password = getpass(fmt);
166
167 if (!password)
168 {
169 memset(password, 0, strlen(password));
170 continue;
171 }
172
173 res = SecKeychainUnlock(m_impl->m_keyChainRef,
174 strlen(password),
175 password,
176 true);
177
178 memset(password, 0, strlen(password));
179
180 if(res == errSecSuccess)
181 locked = false;
182 }
183}
184
185SecTpmOsx::~SecTpmOsx(){
186 //TODO: implement
187}
188
189void
190SecTpmOsx::generateKeyPairInTpm(const Name & keyName, KeyType keyType, int keySize)
191{
192
193 if(doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC)){
194 _LOG_DEBUG("keyName has existed");
195 throw Error("keyName has existed");
196 }
197
198 string keyNameUri = m_impl->toInternalKeyName(keyName, KEY_CLASS_PUBLIC);
199
200 SecKeyRef publicKey, privateKey;
201
202 CFStringRef keyLabel = CFStringCreateWithCString(NULL,
203 keyNameUri.c_str(),
204 kCFStringEncodingUTF8);
205
206 CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(NULL,
207 3,
208 &kCFTypeDictionaryKeyCallBacks,
209 NULL);
210
211 CFDictionaryAddValue(attrDict, kSecAttrKeyType, m_impl->getAsymKeyType(keyType));
212 CFDictionaryAddValue(attrDict, kSecAttrKeySizeInBits, CFNumberCreate(NULL, kCFNumberIntType, &keySize));
213 CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
214
215 OSStatus res = SecKeyGeneratePair((CFDictionaryRef)attrDict, &publicKey, &privateKey);
216
217 CFRelease(publicKey);
218 CFRelease(privateKey);
219
220 if (res != errSecSuccess){
221 _LOG_DEBUG("Fail to create a key pair: " << res);
222 throw Error("Fail to create a key pair");
223 }
224}
225
226void
227SecTpmOsx::deleteKeyPairInTpm(const Name &keyName)
228{
229 string keyNameUri = keyName.toUri();
230
231 CFStringRef keyLabel = CFStringCreateWithCString(NULL,
232 keyNameUri.c_str(),
233 kCFStringEncodingUTF8);
234
235 CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(NULL,
236 5,
237 &kCFTypeDictionaryKeyCallBacks,
238 NULL);
239
240 CFDictionaryAddValue(attrDict, kSecClass, kSecClassKey);
241 CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
242 CFDictionaryAddValue(attrDict, kSecMatchLimit, kSecMatchLimitAll);
243
244 OSStatus res = SecItemDelete((CFDictionaryRef) attrDict);
245
246 if(res != errSecSuccess)
247 _LOG_DEBUG("Fail to find the key!");
248}
249
250void
251SecTpmOsx::generateSymmetricKeyInTpm(const Name & keyName, KeyType keyType, int keySize)
252{
253
254 if(doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
255 throw Error("keyName has existed!");
256
257 string keyNameUri = m_impl->toInternalKeyName(keyName, KEY_CLASS_SYMMETRIC);
258
259 CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(kCFAllocatorDefault,
260 0,
261 &kCFTypeDictionaryKeyCallBacks,
262 &kCFTypeDictionaryValueCallBacks);
263
264 CFStringRef keyLabel = CFStringCreateWithCString(NULL,
265 keyNameUri.c_str(),
266 kCFStringEncodingUTF8);
267
268 CFDictionaryAddValue(attrDict, kSecAttrKeyType, m_impl->getSymKeyType(keyType));
269 CFDictionaryAddValue(attrDict, kSecAttrKeySizeInBits, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &keySize));
270 CFDictionaryAddValue(attrDict, kSecAttrIsPermanent, kCFBooleanTrue);
271 CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
272
273 CFErrorRef error = NULL;
274
275 SecKeyRef symmetricKey = SecKeyGenerateSymmetric(attrDict, &error);
276
277 if (error)
278 throw Error("Fail to create a symmetric key");
279}
280
281ptr_lib::shared_ptr<PublicKey>
282SecTpmOsx::getPublicKeyFromTpm(const Name & keyName)
283{
284 _LOG_TRACE("OSXPrivateKeyStorage::getPublickey");
285
286 SecKeychainItemRef publicKey = m_impl->getKey(keyName, KEY_CLASS_PUBLIC);
287
288 CFDataRef exportedKey;
289
290 OSStatus res = SecItemExport(publicKey,
291 kSecFormatOpenSSL,
292 0,
293 NULL,
294 &exportedKey);
295
296 return ptr_lib::make_shared<PublicKey>(CFDataGetBytePtr(exportedKey), CFDataGetLength(exportedKey));
297}
298
299Block
300SecTpmOsx::signInTpm(const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm)
301{
302 _LOG_TRACE("OSXPrivateKeyStorage::Sign");
303
304 CFDataRef dataRef = CFDataCreateWithBytesNoCopy(NULL,
305 data,
306 dataLength,
307 kCFAllocatorNull
308 );
309
310 SecKeyRef privateKey = (SecKeyRef)m_impl->getKey(keyName, KEY_CLASS_PRIVATE);
311
312 CFErrorRef error;
313 SecTransformRef signer = SecSignTransformCreate((SecKeyRef)privateKey, &error);
314 if (error) throw Error("Fail to create signer");
315
316 // Set input
317 Boolean set_res = SecTransformSetAttribute(signer,
318 kSecTransformInputAttributeName,
319 dataRef,
320 &error);
321 if (error) throw Error("Fail to configure input of signer");
322
323 // Enable use of padding
324 SecTransformSetAttribute(
325 signer,
326 kSecPaddingKey,
327 kSecPaddingPKCS1Key,
328 &error);
329 if (error) throw Error("Fail to configure digest algorithm of signer");
330
331 // Set padding type
332 set_res = SecTransformSetAttribute(signer,
333 kSecDigestTypeAttribute,
334 m_impl->getDigestAlgorithm(digestAlgorithm),
335 &error);
336 if (error) throw Error("Fail to configure digest algorithm of signer");
337
338 // Set padding attribute
339 long digestSize = m_impl->getDigestSize(digestAlgorithm);
340 set_res = SecTransformSetAttribute(signer,
341 kSecDigestLengthAttribute,
342 CFNumberCreate(NULL, kCFNumberLongType, &digestSize),
343 &error);
344 if (error) throw Error("Fail to configure digest size of signer");
345
346 // Actually sign
347 CFDataRef signature = (CFDataRef) SecTransformExecute(signer, &error);
348 if (error) {
349 CFShow(error);
350 throw Error("Fail to sign data");
351 }
352
353 if (!signature) throw Error("Signature is NULL!\n");
354
355 return Block(Tlv::SignatureValue,
356 ptr_lib::make_shared<Buffer>(CFDataGetBytePtr(signature), CFDataGetLength(signature)));
357}
358
359ConstBufferPtr
360SecTpmOsx::decryptInTpm(const Name & keyName, const uint8_t* data, size_t dataLength, bool sym)
361{
362 _LOG_TRACE("OSXPrivateKeyStorage::Decrypt");
363
364 KeyClass keyClass;
365 if(sym)
366 keyClass = KEY_CLASS_SYMMETRIC;
367 else
368 keyClass = KEY_CLASS_PRIVATE;
369
370 CFDataRef dataRef = CFDataCreate(NULL,
371 reinterpret_cast<const unsigned char*>(data),
372 dataLength
373 );
374
375 // _LOG_DEBUG("CreateData");
376
377 SecKeyRef decryptKey = (SecKeyRef)m_impl->getKey(keyName, keyClass);
378
379 // _LOG_DEBUG("GetKey");
380
381 CFErrorRef error;
382 SecTransformRef decrypt = SecDecryptTransformCreate(decryptKey, &error);
383 if (error) throw Error("Fail to create decrypt");
384
385 Boolean set_res = SecTransformSetAttribute(decrypt,
386 kSecTransformInputAttributeName,
387 dataRef,
388 &error);
389 if (error) throw Error("Fail to configure decrypt");
390
391 CFDataRef output = (CFDataRef) SecTransformExecute(decrypt, &error);
392 if (error)
393 {
394 CFShow(error);
395 throw Error("Fail to decrypt data");
396 }
397 if (!output) throw Error("Output is NULL!\n");
398
399 return ptr_lib::make_shared<Buffer>(CFDataGetBytePtr(output), CFDataGetLength(output));
400}
401
402bool
403SecTpmOsx::setACL(const Name & keyName, KeyClass keyClass, int acl, const string & appPath)
404{
405 SecKeychainItemRef privateKey = m_impl->getKey(keyName, keyClass);
406
407 SecAccessRef accRef;
408 OSStatus acc_res = SecKeychainItemCopyAccess(privateKey, &accRef);
409
410 CFArrayRef signACL = SecAccessCopyMatchingACLList(accRef,
411 kSecACLAuthorizationSign);
412
413 SecACLRef aclRef = (SecACLRef) CFArrayGetValueAtIndex(signACL, 0);
414
415 CFArrayRef appList;
416 CFStringRef description;
417 SecKeychainPromptSelector promptSelector;
418 OSStatus acl_res = SecACLCopyContents(aclRef,
419 &appList,
420 &description,
421 &promptSelector);
422
423 CFMutableArrayRef newAppList = CFArrayCreateMutableCopy(NULL,
424 0,
425 appList);
426
427 SecTrustedApplicationRef trustedApp;
428 acl_res = SecTrustedApplicationCreateFromPath(appPath.c_str(),
429 &trustedApp);
430
431 CFArrayAppendValue(newAppList, trustedApp);
432
433
434 CFArrayRef authList = SecACLCopyAuthorizations(aclRef);
435
436 acl_res = SecACLRemove(aclRef);
437
438 SecACLRef newACL;
439 acl_res = SecACLCreateWithSimpleContents(accRef,
440 newAppList,
441 description,
442 promptSelector,
443 &newACL);
444
445 acl_res = SecACLUpdateAuthorizations(newACL, authList);
446
447 acc_res = SecKeychainItemSetAccess(privateKey, accRef);
448
449 return true;
450}
451
452// bool
453// OSXPrivateKeyStorage::verifyData(const Name & keyName, const Blob & pData, const Blob & pSig, DigestAlgorithm digestAlgo)
454// {
455// _LOG_TRACE("OSXPrivateKeyStorage::Verify");
456
457// CFDataRef dataRef = CFDataCreate(NULL,
458// reinterpret_cast<const unsigned char*>(pData.buf()),
459// pData.size());
460
461// CFDataRef sigRef = CFDataCreate(NULL,
462// reinterpret_cast<const unsigned char*>(pSig.buf()),
463// pSig.size());
464
465// SecKeyRef publicKey = (SecKeyRef)m_impl->getKey(keyName, KEY_CLASS_PUBLIC);
466
467// CFErrorRef error;
468// SecTransformRef verifier = SecVerifyTransformCreate(publicKey, sigRef, &error);
469// if (error) throw Error("Fail to create verifier");
470
471// Boolean set_res = SecTransformSetAttribute(verifier,
472// kSecTransformInputAttributeName,
473// dataRef,
474// &error);
475// if (error) throw Error("Fail to configure input of verifier");
476
477// set_res = SecTransformSetAttribute(verifier,
478// kSecDigestTypeAttribute,
479// m_impl->getDigestAlgorithm(digestAlgo),
480// &error);
481// if (error) throw Error("Fail to configure digest algorithm of verifier");
482
483// long digestSize = m_impl->getDigestSize(digestAlgo);
484// set_res = SecTransformSetAttribute(verifier,
485// kSecDigestLengthAttribute,
486// CFNumberCreate(NULL, kCFNumberLongType, &digestSize),
487// &error);
488// if (error) throw Error("Fail to configure digest size of verifier");
489
490// CFBooleanRef result = (CFBooleanRef) SecTransformExecute(verifier, &error);
491// if (error) throw Error("Fail to verify data");
492
493// if (result == kCFBooleanTrue)
494// return true;
495// else
496// return false;
497// }
498
499ConstBufferPtr
500SecTpmOsx::encryptInTpm(const Name & keyName, const uint8_t* data, size_t dataLength, bool sym)
501{
502 _LOG_TRACE("OSXPrivateKeyStorage::Encrypt");
503
504 KeyClass keyClass;
505 if(sym)
506 keyClass = KEY_CLASS_SYMMETRIC;
507 else
508 keyClass = KEY_CLASS_PUBLIC;
509
510 CFDataRef dataRef = CFDataCreate(NULL,
511 reinterpret_cast<const unsigned char*>(data),
512 dataLength
513 );
514
515 SecKeyRef encryptKey = (SecKeyRef)m_impl->getKey(keyName, keyClass);
516
517 CFErrorRef error;
518 SecTransformRef encrypt = SecEncryptTransformCreate(encryptKey, &error);
519 if (error) throw Error("Fail to create encrypt");
520
521 Boolean set_res = SecTransformSetAttribute(encrypt,
522 kSecTransformInputAttributeName,
523 dataRef,
524 &error);
525 if (error) throw Error("Fail to configure encrypt");
526
527 CFDataRef output = (CFDataRef) SecTransformExecute(encrypt, &error);
528 if (error) throw Error("Fail to encrypt data");
529
530 if (!output) throw Error("Output is NULL!\n");
531
532 return ptr_lib::make_shared<Buffer> (CFDataGetBytePtr(output), CFDataGetLength(output));
533}
534
535bool
536SecTpmOsx::doesKeyExistInTpm(const Name & keyName, KeyClass keyClass)
537{
538 _LOG_TRACE("OSXPrivateKeyStorage::doesKeyExist");
539
540 string keyNameUri = m_impl->toInternalKeyName(keyName, keyClass);
541
542 CFStringRef keyLabel = CFStringCreateWithCString(NULL,
543 keyNameUri.c_str(),
544 kCFStringEncodingUTF8);
545
546 CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(NULL,
547 4,
548 &kCFTypeDictionaryKeyCallBacks,
549 NULL);
550
551 CFDictionaryAddValue(attrDict, kSecClass, kSecClassKey);
552 CFDictionaryAddValue(attrDict, kSecAttrKeyClass, m_impl->getKeyClass(keyClass));
553 CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
554 CFDictionaryAddValue(attrDict, kSecReturnRef, kCFBooleanTrue);
555
556 SecKeychainItemRef itemRef;
557 OSStatus res = SecItemCopyMatching((CFDictionaryRef)attrDict, (CFTypeRef*)&itemRef);
558
559 if(res == errSecItemNotFound)
560 return false;
561 else
562 return true;
563
564}
565
Yingdi Yu4b752752014-02-18 12:24:03 -0800566bool
567SecTpmOsx::generateRandomBlock(uint8_t* res, size_t size)
568{
569 return (SecRandomCopyBytes(kSecRandomDefault, size, res) == 0);
570}
Yingdi Yu2b2b4792014-02-04 16:27:07 -0800571
572////////////////////////////////
573// OSXPrivateKeyStorage::Impl //
574////////////////////////////////
575
576SecKeychainItemRef
577SecTpmOsx::Impl::getKey(const Name & keyName, KeyClass keyClass)
578{
579 string keyNameUri = toInternalKeyName(keyName, keyClass);
580
581 CFStringRef keyLabel = CFStringCreateWithCString(NULL,
582 keyNameUri.c_str(),
583 kCFStringEncodingUTF8);
584
585 CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(NULL,
586 5,
587 &kCFTypeDictionaryKeyCallBacks,
588 NULL);
589
590 CFDictionaryAddValue(attrDict, kSecClass, kSecClassKey);
591 CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
592 CFDictionaryAddValue(attrDict, kSecAttrKeyClass, getKeyClass(keyClass));
593 CFDictionaryAddValue(attrDict, kSecReturnRef, kCFBooleanTrue);
594
595 SecKeychainItemRef keyItem;
596
597 OSStatus res = SecItemCopyMatching((CFDictionaryRef) attrDict, (CFTypeRef*)&keyItem);
598
599 if(res != errSecSuccess){
600 _LOG_DEBUG("Fail to find the key!");
601 return NULL;
602 }
603 else
604 return keyItem;
605}
606
607string
608SecTpmOsx::Impl::toInternalKeyName(const Name & keyName, KeyClass keyClass)
609{
610 string keyUri = keyName.toUri();
611
612 if(KEY_CLASS_SYMMETRIC == keyClass)
613 return keyUri + "/symmetric";
614 else
615 return keyUri;
616}
617
618const CFTypeRef
619SecTpmOsx::Impl::getAsymKeyType(KeyType keyType)
620{
621 switch(keyType){
622 case KEY_TYPE_RSA:
623 return kSecAttrKeyTypeRSA;
624 default:
625 _LOG_DEBUG("Unrecognized key type!")
626 return NULL;
627 }
628}
629
630const CFTypeRef
631SecTpmOsx::Impl::getSymKeyType(KeyType keyType)
632{
633 switch(keyType){
634 case KEY_TYPE_AES:
635 return kSecAttrKeyTypeAES;
636 default:
637 _LOG_DEBUG("Unrecognized key type!")
638 return NULL;
639 }
640}
641
642const CFTypeRef
643SecTpmOsx::Impl::getKeyClass(KeyClass keyClass)
644{
645 switch(keyClass){
646 case KEY_CLASS_PRIVATE:
647 return kSecAttrKeyClassPrivate;
648 case KEY_CLASS_PUBLIC:
649 return kSecAttrKeyClassPublic;
650 case KEY_CLASS_SYMMETRIC:
651 return kSecAttrKeyClassSymmetric;
652 default:
653 _LOG_DEBUG("Unrecognized key class!");
654 return NULL;
655 }
656}
657
658const CFStringRef
659SecTpmOsx::Impl::getDigestAlgorithm(DigestAlgorithm digestAlgo)
660{
661 switch(digestAlgo){
Jeff Thompson2747dc02013-10-04 19:11:34 -0700662 // case DIGEST_MD2:
663 // return kSecDigestMD2;
664 // case DIGEST_MD5:
665 // return kSecDigestMD5;
666 // case DIGEST_SHA1:
667 // return kSecDigestSHA1;
Yingdi Yu2b2b4792014-02-04 16:27:07 -0800668 case DIGEST_ALGORITHM_SHA256:
669 return kSecDigestSHA2;
670 default:
671 _LOG_DEBUG("Unrecognized digest algorithm!");
672 return NULL;
Jeff Thompson2747dc02013-10-04 19:11:34 -0700673 }
Yingdi Yu2b2b4792014-02-04 16:27:07 -0800674}
Jeff Thompson2747dc02013-10-04 19:11:34 -0700675
Yingdi Yu2b2b4792014-02-04 16:27:07 -0800676long
677SecTpmOsx::Impl::getDigestSize(DigestAlgorithm digestAlgo)
678{
679 switch(digestAlgo){
680 case DIGEST_ALGORITHM_SHA256:
681 return 256;
Jeff Thompson2747dc02013-10-04 19:11:34 -0700682 // case DIGEST_SHA1:
683 // case DIGEST_MD2:
684 // case DIGEST_MD5:
685 // return 0;
Yingdi Yu2b2b4792014-02-04 16:27:07 -0800686 default:
687 _LOG_DEBUG("Unrecognized digest algorithm! Unknown digest size");
688 return -1;
Jeff Thompson2747dc02013-10-04 19:11:34 -0700689 }
Jeff Thompson2747dc02013-10-04 19:11:34 -0700690}
Yingdi Yu2b2b4792014-02-04 16:27:07 -0800691
692bool
693SecTpmOsx::Impl::getPassWord(string& password, string target)
694{
695 int result = false;
696
697 string prompt1 = "Password for " + target + ":";
698 string prompt2 = "Confirm password for " + target + ":";
699 char* pw0 = NULL;
700
701 pw0 = getpass(prompt1.c_str());
702 if(!pw0)
703 return false;
704 string password1 = pw0;
705 memset(pw0, 0, strlen(pw0));
706
707 pw0 = getpass(prompt2.c_str());
708 if(!pw0)
709 {
710 char* pw1 = const_cast<char*>(password1.c_str());
711 memset(pw1, 0, password1.size());
712 return false;
713 }
714
715 if(!password1.compare(pw0))
716 {
717 result = true;
718 password.swap(password1);
719 }
720
721 char* pw1 = const_cast<char*>(password1.c_str());
722 memset(pw1, 0, password1.size());
723 memset(pw0, 0, strlen(pw0));
724 return result;
725}
726
727}// ndn