]>
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>
40 Error::Error(MSC_RV err
) : error(err
)
42 SECURITY_EXCEPTION_THROW_OTHER(this, err
, (char *)"muscle");
43 secnotice("security_exception", "muscle: %d", err
);
47 const char *Error::what() const throw ()
49 return msc_error(error
);
53 void Error::throwMe(MSC_RV err
)
59 OSStatus
Error::osStatus() const
61 return -1; //@@@ preliminary
64 int Error::unixError() const
66 return EINVAL
; //@@@ preliminary
71 // Open a connection with PCSC layer information.
72 // The ReaderState fields required are the slot name and the ATR.
74 Connection::Connection()
75 : mIsOpen(false), mCurrentTransaction(NULL
)
79 Connection::~Connection()
81 assert(!mCurrentTransaction
);
85 void Connection::open(const PCSC::ReaderState
&reader
, unsigned share
)
87 // fill in the minimum needed to identify the card
90 // set slot name in info
91 strncpy(info
.slotName
, reader
.name(), MAX_READERNAME
);
94 assert(reader
.length() <= MAX_ATR_SIZE
);
95 memcpy(info
.tokenId
, reader
.data(), reader
.length());
96 info
.tokenIdLength
= (MSCULong32
)reader
.length();
98 // establish Muscle-level connection to card
99 Error::check(::MSCEstablishConnection(&info
, share
, NULL
, 0, this));
101 secinfo("muscle", "%p opened %s", this, info
.slotName
);
103 // pull initial status
107 void Connection::close()
110 secinfo("muscle", "%p closing", this);
111 Error::check(::MSCReleaseConnection(this, SCARD_LEAVE_CARD
));
117 void Connection::begin(Transaction
*trans
)
119 assert(!mCurrentTransaction
);
120 Error::check(::MSCBeginTransaction(this));
121 secinfo("muscle", "%p start transaction %p", this, trans
);
122 mCurrentTransaction
= trans
;
125 void Connection::end(Transaction
*trans
)
127 assert(trans
== mCurrentTransaction
);
128 secinfo("muscle", "%p end transaction %p", this, trans
);
129 Error::check(::MSCEndTransaction(this, SCARD_LEAVE_CARD
));
130 mCurrentTransaction
= NULL
;
135 // Update card status (cached in the Connection object)
137 void Connection::updateStatus()
139 Error::check(::MSCGetStatus(this, this));
144 // Get all items off the card
146 template <class Info
, class Item
, MSC_RV (*list
)(MSCTokenConnection
*, MSCUChar8
, Info
*)>
147 static void get(Connection
*conn
, Connection::ItemSet
&items
)
150 MSCUChar8 seq
= MSC_SEQUENCE_RESET
;
152 switch (MSC_RV rc
= list(conn
, seq
, &info
)) {
153 case MSC_SEQUENCE_END
:
156 items
.insert(new Item(info
));
157 seq
= MSC_SEQUENCE_NEXT
;
165 void Connection::getItems(ItemSet
&result
, bool getKeys
, bool getOthers
)
169 get
<MSCKeyInfo
, Key
, MSCListKeys
>(this, items
);
171 get
<MSCObjectInfo
, Object
, MSCListObjects
>(this, items
);
177 // Transaction monitors
179 Transaction::Transaction(Connection
&con
)
182 connection
.begin(this);
185 Transaction::~Transaction()
187 connection
.end(this);
192 // ACLs (Muscle style)
194 static void aclForm(string
&s
, MSCUShort16 acl
, int offset
, char c
)
196 for (int n
= 0; n
< 5; n
++) {
199 case MSC_AUT_ALL
: p
= c
; break;
200 case MSC_AUT_NONE
: break;
201 default: if (acl
& (MSC_AUT_PIN_0
<< n
)) p
= c
; break;
203 s
[3 * n
+ offset
] = p
;
207 string
ACL::form(char ue
) const
209 string r
= "---------------";
210 aclForm(r
, mRead
, 0, 'r');
211 aclForm(r
, mWrite
, 1, 'w');
212 aclForm(r
, mErase
, 2, ue
);
220 CardItem::~CardItem()
224 Key::Key(const MSCKeyInfo
&info
)
227 snprintf(mKeyName
, sizeof(mKeyName
), "K%d", id());
231 const ACL
&Key::acl() const { return reinterpret_cast<const ACL
&>(keyACL
); }
232 ACL
&Key::acl() { return reinterpret_cast<ACL
&>(keyACL
); }
234 const char *Key::name() const { return mKeyName
; }
235 unsigned Key::size() const { return keySize
; }
237 void Key::debugDump()
239 printf("Key %d type %d size %d mode=0x%x dir=0x%x ACL %s\n",
240 keyNum
, keyType
, keySize
, mode(), operations(), acl().form('u').c_str());
243 const char *Object::name() const { return objectID
; }
244 unsigned Object::size() const { return objectSize
; }
246 const ACL
&Object::acl() const { return reinterpret_cast<const ACL
&>(objectACL
); }
247 ACL
&Object::acl() { return reinterpret_cast<ACL
&>(objectACL
); }
249 void Object::debugDump()
251 printf("Object %s size %d ACL %s\n",
252 objectID
, objectSize
, acl().form('e').c_str());
256 } // namespace Muscle
257 } // namespace Security