]>
git.saurik.com Git - apple/security.git/blob - Security/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>
40 Error::Error(MSC_RV err
) : error(err
)
42 SECURITY_EXCEPTION_THROW_OTHER(this, err
, (char *)"muscle");
46 const char *Error::what() const throw ()
48 return msc_error(error
);
52 void Error::throwMe(MSC_RV err
)
58 OSStatus
Error::osStatus() const
60 return -1; //@@@ preliminary
63 int Error::unixError() const
65 return EINVAL
; //@@@ preliminary
70 // Open a connection with PCSC layer information.
71 // The ReaderState fields required are the slot name and the ATR.
73 Connection::Connection()
74 : mIsOpen(false), mCurrentTransaction(NULL
)
78 Connection::~Connection()
80 assert(!mCurrentTransaction
);
84 void Connection::open(const PCSC::ReaderState
&reader
, unsigned share
)
86 // fill in the minimum needed to identify the card
89 // set slot name in info
90 strncpy(info
.slotName
, reader
.name(), MAX_READERNAME
);
93 assert(reader
.length() <= MAX_ATR_SIZE
);
94 memcpy(info
.tokenId
, reader
.data(), reader
.length());
95 info
.tokenIdLength
= (MSCULong32
)reader
.length();
97 // establish Muscle-level connection to card
98 Error::check(::MSCEstablishConnection(&info
, share
, NULL
, 0, this));
100 secdebug("muscle", "%p opened %s", this, info
.slotName
);
102 // pull initial status
106 void Connection::close()
109 secdebug("muscle", "%p closing", this);
110 Error::check(::MSCReleaseConnection(this, SCARD_LEAVE_CARD
));
116 void Connection::begin(Transaction
*trans
)
118 assert(!mCurrentTransaction
);
119 Error::check(::MSCBeginTransaction(this));
120 secdebug("muscle", "%p start transaction %p", this, trans
);
121 mCurrentTransaction
= trans
;
124 void Connection::end(Transaction
*trans
)
126 assert(trans
== mCurrentTransaction
);
127 secdebug("muscle", "%p end transaction %p", this, trans
);
128 Error::check(::MSCEndTransaction(this, SCARD_LEAVE_CARD
));
129 mCurrentTransaction
= NULL
;
134 // Update card status (cached in the Connection object)
136 void Connection::updateStatus()
138 Error::check(::MSCGetStatus(this, this));
143 // Get all items off the card
145 template <class Info
, class Item
, MSC_RV (*list
)(MSCTokenConnection
*, MSCUChar8
, Info
*)>
146 static void get(Connection
*conn
, Connection::ItemSet
&items
)
149 MSCUChar8 seq
= MSC_SEQUENCE_RESET
;
151 switch (MSC_RV rc
= list(conn
, seq
, &info
)) {
152 case MSC_SEQUENCE_END
:
155 items
.insert(new Item(info
));
156 seq
= MSC_SEQUENCE_NEXT
;
164 void Connection::getItems(ItemSet
&result
, bool getKeys
, bool getOthers
)
168 get
<MSCKeyInfo
, Key
, MSCListKeys
>(this, items
);
170 get
<MSCObjectInfo
, Object
, MSCListObjects
>(this, items
);
176 // Transaction monitors
178 Transaction::Transaction(Connection
&con
)
181 connection
.begin(this);
184 Transaction::~Transaction()
186 connection
.end(this);
191 // ACLs (Muscle style)
193 static void aclForm(string
&s
, MSCUShort16 acl
, int offset
, char c
)
195 for (int n
= 0; n
< 5; n
++) {
198 case MSC_AUT_ALL
: p
= c
; break;
199 case MSC_AUT_NONE
: break;
200 default: if (acl
& (MSC_AUT_PIN_0
<< n
)) p
= c
; break;
202 s
[3 * n
+ offset
] = p
;
206 string
ACL::form(char ue
) const
208 string r
= "---------------";
209 aclForm(r
, mRead
, 0, 'r');
210 aclForm(r
, mWrite
, 1, 'w');
211 aclForm(r
, mErase
, 2, ue
);
219 CardItem::~CardItem()
223 Key::Key(const MSCKeyInfo
&info
)
226 snprintf(mKeyName
, sizeof(mKeyName
), "K%d", id());
230 const ACL
&Key::acl() const { return reinterpret_cast<const ACL
&>(keyACL
); }
231 ACL
&Key::acl() { return reinterpret_cast<ACL
&>(keyACL
); }
233 const char *Key::name() const { return mKeyName
; }
234 unsigned Key::size() const { return keySize
; }
236 void Key::debugDump()
238 printf("Key %d type %d size %d mode=0x%x dir=0x%x ACL %s\n",
239 keyNum
, keyType
, keySize
, mode(), operations(), acl().form('u').c_str());
242 const char *Object::name() const { return objectID
; }
243 unsigned Object::size() const { return objectSize
; }
245 const ACL
&Object::acl() const { return reinterpret_cast<const ACL
&>(objectACL
); }
246 ACL
&Object::acl() { return reinterpret_cast<ACL
&>(objectACL
); }
248 void Object::debugDump()
250 printf("Object %s size %d ACL %s\n",
251 objectID
, objectSize
, acl().form('e').c_str());
255 } // namespace Muscle
256 } // namespace Security