1/* 2 * Copyright (c) 2000-2006,2011,2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25// 26// acl_prompted - password-based validation with out-of-band prompting. 27// 28#include <security_cdsa_utilities/acl_prompted.h> 29#include <security_utilities/debugging.h> 30#include <security_utilities/endian.h> 31#include <algorithm> 32 33 34// 35// Construct PromptedAclSubjects from prompts and optional data 36// 37PromptedAclSubject::PromptedAclSubject(Allocator &alloc, 38 const CssmData &prompt, const CssmData &password) 39 : SecretAclSubject(alloc, CSSM_ACL_SUBJECT_TYPE_PROMPTED_PASSWORD, password), 40 mPrompt(alloc, prompt) { } 41PromptedAclSubject::PromptedAclSubject(Allocator &alloc, 42 CssmManagedData &prompt, CssmManagedData &password) 43 : SecretAclSubject(alloc, CSSM_ACL_SUBJECT_TYPE_PROMPTED_PASSWORD, password), 44 mPrompt(alloc, prompt) { } 45PromptedAclSubject::PromptedAclSubject(Allocator &alloc, 46 const CssmData &prompt, bool cache) 47 : SecretAclSubject(alloc, CSSM_ACL_SUBJECT_TYPE_PROMPTED_PASSWORD, cache), 48 mPrompt(alloc, prompt) { } 49 50 51// 52// PromptedAclSubject will prompt for the secret 53// 54bool PromptedAclSubject::getSecret(const AclValidationContext &context, 55 const TypedList &subject, CssmOwnedData &secret) const 56{ 57 if (Environment *env = context.environment<Environment>()) { 58 return env->getSecret(secret, mPrompt); 59 } else { 60 return false; 61 } 62} 63 64 65// 66// Make a copy of this subject in CSSM_LIST form 67// 68CssmList PromptedAclSubject::toList(Allocator &alloc) const 69{ 70 // the password itself is private and not exported to CSSM 71 return TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_PROMPTED_PASSWORD, 72 new(alloc) ListElement(alloc, mPrompt)); 73} 74 75 76// 77// Create a PromptedAclSubject 78// 79PromptedAclSubject *PromptedAclSubject::Maker::make(const TypedList &list) const 80{ 81 Allocator &alloc = Allocator::standard(Allocator::sensitive); 82 switch (list.length()) { 83 case 2: 84 { 85 ListElement *elem[1]; 86 crack(list, 1, elem, CSSM_LIST_ELEMENT_DATUM); 87 return new PromptedAclSubject(alloc, elem[0]->data(), true); 88 } 89 case 3: 90 { 91 ListElement *elem[2]; 92 crack(list, 2, elem, CSSM_LIST_ELEMENT_DATUM, CSSM_LIST_ELEMENT_DATUM); 93 return new PromptedAclSubject(alloc, elem[0]->data(), elem[1]->data()); 94 } 95 default: 96 CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE); 97 } 98} 99 100PromptedAclSubject *PromptedAclSubject::Maker::make(Version, Reader &pub, Reader &priv) const 101{ 102 Allocator &alloc = Allocator::standard(Allocator::sensitive); 103 const void *data; size_t length; priv.countedData(data, length); 104 return new PromptedAclSubject(alloc, CssmAutoData(alloc, data, length), true); 105} 106 107 108// 109// Export the subject to a memory blob 110// 111void PromptedAclSubject::exportBlob(Writer::Counter &pub, Writer::Counter &priv) 112{ 113 pub.countedData(mPrompt); 114} 115 116void PromptedAclSubject::exportBlob(Writer &pub, Writer &priv) 117{ 118 pub.countedData(mPrompt); 119} 120 121 122#ifdef DEBUGDUMP 123 124void PromptedAclSubject::debugDump() const 125{ 126 Debug::dump("Prompted-Password"); 127 SecretAclSubject::debugDump(); 128} 129 130#endif //DEBUGDUMP 131