]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_utilities/lib/muscle++.cpp
2 * Copyright (c) 2004,2011-2012,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
27 // C++ gate to "Muscle" smartcard interface layer
30 #include <security_utilities/debugging.h>
41 Error::Error(MSC_RV err
) : error(err
)
43 SECURITY_EXCEPTION_THROW_OTHER(this, err
, (char *)"muscle");
44 secnotice("security_exception", "muscle: %d", err
);
48 const char *Error::what() const _NOEXCEPT
50 return msc_error(error
);
54 void Error::throwMe(MSC_RV err
)
60 OSStatus
Error::osStatus() const
62 return -1; //@@@ preliminary
65 int Error::unixError() const
67 return EINVAL
; //@@@ preliminary
72 // Open a connection with PCSC layer information.
73 // The ReaderState fields required are the slot name and the ATR.
75 Connection::Connection()
76 : mIsOpen(false), mCurrentTransaction(NULL
)
80 Connection::~Connection()
82 assert(!mCurrentTransaction
);
86 void Connection::open(const PCSC::ReaderState
&reader
, unsigned share
)
88 // fill in the minimum needed to identify the card
91 // set slot name in info
92 strncpy(info
.slotName
, reader
.name(), MAX_READERNAME
);
95 if (reader
.length() > MAX_ATR_SIZE
) {
96 Error::throwMe(MSC_INVALID_PARAMETER
);
99 memcpy(info
.tokenId
, reader
.data(), reader
.length());
100 info
.tokenIdLength
= (MSCULong32
)reader
.length();
102 // establish Muscle-level connection to card
103 Error::check(::MSCEstablishConnection(&info
, share
, NULL
, 0, this));
105 secinfo("muscle", "%p opened %s", this, info
.slotName
);
107 // pull initial status
111 void Connection::close()
114 secinfo("muscle", "%p closing", this);
115 Error::check(::MSCReleaseConnection(this, SCARD_LEAVE_CARD
));
121 void Connection::begin(Transaction
*trans
)
123 assert(!mCurrentTransaction
);
124 Error::check(::MSCBeginTransaction(this));
125 secinfo("muscle", "%p start transaction %p", this, trans
);
126 mCurrentTransaction
= trans
;
129 void Connection::end(Transaction
*trans
)
131 assert(trans
== mCurrentTransaction
);
132 secinfo("muscle", "%p end transaction %p", this, trans
);
133 Error::check(::MSCEndTransaction(this, SCARD_LEAVE_CARD
));
134 mCurrentTransaction
= NULL
;
139 // Update card status (cached in the Connection object)
141 void Connection::updateStatus()
143 Error::check(::MSCGetStatus(this, this));
148 // Get all items off the card
150 template <class Info
, class Item
, MSC_RV (*list
)(MSCTokenConnection
*, MSCUChar8
, Info
*)>
151 static void get(Connection
*conn
, Connection::ItemSet
&items
)
154 MSCUChar8 seq
= MSC_SEQUENCE_RESET
;
156 switch (MSC_RV rc
= list(conn
, seq
, &info
)) {
157 case MSC_SEQUENCE_END
:
160 items
.insert(new Item(info
));
161 seq
= MSC_SEQUENCE_NEXT
;
169 void Connection::getItems(ItemSet
&result
, bool getKeys
, bool getOthers
)
173 get
<MSCKeyInfo
, Key
, MSCListKeys
>(this, items
);
175 get
<MSCObjectInfo
, Object
, MSCListObjects
>(this, items
);
181 // Transaction monitors
183 Transaction::Transaction(Connection
&con
)
186 connection
.begin(this);
189 Transaction::~Transaction()
191 connection
.end(this);
196 // ACLs (Muscle style)
198 static void aclForm(string
&s
, MSCUShort16 acl
, int offset
, char c
)
200 for (int n
= 0; n
< 5; n
++) {
203 case MSC_AUT_ALL
: p
= c
; break;
204 case MSC_AUT_NONE
: break;
205 default: if (acl
& (MSC_AUT_PIN_0
<< n
)) p
= c
; break;
207 s
[3 * n
+ offset
] = p
;
211 string
ACL::form(char ue
) const
213 string r
= "---------------";
214 aclForm(r
, mRead
, 0, 'r');
215 aclForm(r
, mWrite
, 1, 'w');
216 aclForm(r
, mErase
, 2, ue
);
224 CardItem::~CardItem()
228 Key::Key(const MSCKeyInfo
&info
)
231 snprintf(mKeyName
, sizeof(mKeyName
), "K%d", id());
235 const ACL
&Key::acl() const { return reinterpret_cast<const ACL
&>(keyACL
); }
236 ACL
&Key::acl() { return reinterpret_cast<ACL
&>(keyACL
); }
238 const char *Key::name() const { return mKeyName
; }
239 unsigned Key::size() const { return keySize
; }
241 void Key::debugDump()
243 printf("Key %d type %d size %d mode=0x%x dir=0x%x ACL %s\n",
244 keyNum
, keyType
, keySize
, mode(), operations(), acl().form('u').c_str());
247 const char *Object::name() const { return objectID
; }
248 unsigned Object::size() const { return objectSize
; }
250 const ACL
&Object::acl() const { return reinterpret_cast<const ACL
&>(objectACL
); }
251 ACL
&Object::acl() { return reinterpret_cast<ACL
&>(objectACL
); }
253 void Object::debugDump()
255 printf("Object %s size %d ACL %s\n",
256 objectID
, objectSize
, acl().form('e').c_str());
260 } // namespace Muscle
261 } // namespace Security
263 #endif //TARGET_OS_OSX