]>
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 throw ()
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 assert(reader
.length() <= MAX_ATR_SIZE
);
96 memcpy(info
.tokenId
, reader
.data(), reader
.length());
97 info
.tokenIdLength
= (MSCULong32
)reader
.length();
99 // establish Muscle-level connection to card
100 Error::check(::MSCEstablishConnection(&info
, share
, NULL
, 0, this));
102 secinfo("muscle", "%p opened %s", this, info
.slotName
);
104 // pull initial status
108 void Connection::close()
111 secinfo("muscle", "%p closing", this);
112 Error::check(::MSCReleaseConnection(this, SCARD_LEAVE_CARD
));
118 void Connection::begin(Transaction
*trans
)
120 assert(!mCurrentTransaction
);
121 Error::check(::MSCBeginTransaction(this));
122 secinfo("muscle", "%p start transaction %p", this, trans
);
123 mCurrentTransaction
= trans
;
126 void Connection::end(Transaction
*trans
)
128 assert(trans
== mCurrentTransaction
);
129 secinfo("muscle", "%p end transaction %p", this, trans
);
130 Error::check(::MSCEndTransaction(this, SCARD_LEAVE_CARD
));
131 mCurrentTransaction
= NULL
;
136 // Update card status (cached in the Connection object)
138 void Connection::updateStatus()
140 Error::check(::MSCGetStatus(this, this));
145 // Get all items off the card
147 template <class Info
, class Item
, MSC_RV (*list
)(MSCTokenConnection
*, MSCUChar8
, Info
*)>
148 static void get(Connection
*conn
, Connection::ItemSet
&items
)
151 MSCUChar8 seq
= MSC_SEQUENCE_RESET
;
153 switch (MSC_RV rc
= list(conn
, seq
, &info
)) {
154 case MSC_SEQUENCE_END
:
157 items
.insert(new Item(info
));
158 seq
= MSC_SEQUENCE_NEXT
;
166 void Connection::getItems(ItemSet
&result
, bool getKeys
, bool getOthers
)
170 get
<MSCKeyInfo
, Key
, MSCListKeys
>(this, items
);
172 get
<MSCObjectInfo
, Object
, MSCListObjects
>(this, items
);
178 // Transaction monitors
180 Transaction::Transaction(Connection
&con
)
183 connection
.begin(this);
186 Transaction::~Transaction()
188 connection
.end(this);
193 // ACLs (Muscle style)
195 static void aclForm(string
&s
, MSCUShort16 acl
, int offset
, char c
)
197 for (int n
= 0; n
< 5; n
++) {
200 case MSC_AUT_ALL
: p
= c
; break;
201 case MSC_AUT_NONE
: break;
202 default: if (acl
& (MSC_AUT_PIN_0
<< n
)) p
= c
; break;
204 s
[3 * n
+ offset
] = p
;
208 string
ACL::form(char ue
) const
210 string r
= "---------------";
211 aclForm(r
, mRead
, 0, 'r');
212 aclForm(r
, mWrite
, 1, 'w');
213 aclForm(r
, mErase
, 2, ue
);
221 CardItem::~CardItem()
225 Key::Key(const MSCKeyInfo
&info
)
228 snprintf(mKeyName
, sizeof(mKeyName
), "K%d", id());
232 const ACL
&Key::acl() const { return reinterpret_cast<const ACL
&>(keyACL
); }
233 ACL
&Key::acl() { return reinterpret_cast<ACL
&>(keyACL
); }
235 const char *Key::name() const { return mKeyName
; }
236 unsigned Key::size() const { return keySize
; }
238 void Key::debugDump()
240 printf("Key %d type %d size %d mode=0x%x dir=0x%x ACL %s\n",
241 keyNum
, keyType
, keySize
, mode(), operations(), acl().form('u').c_str());
244 const char *Object::name() const { return objectID
; }
245 unsigned Object::size() const { return objectSize
; }
247 const ACL
&Object::acl() const { return reinterpret_cast<const ACL
&>(objectACL
); }
248 ACL
&Object::acl() { return reinterpret_cast<ACL
&>(objectACL
); }
250 void Object::debugDump()
252 printf("Object %s size %d ACL %s\n",
253 objectID
, objectSize
, acl().form('e').c_str());
257 } // namespace Muscle
258 } // namespace Security
260 #endif //TARGET_OS_OSX