Hi,
Here is an older mail which describes how this is done. Please note that this is not
any standard method for modeling data on a smart card. This was chosen as a simple
way to associate PKCS#11 attributes with an associated object.
My suggestion to you is that if you want to store certificates with another program, use PKCS#11 as the API
to do this. This will allow you to re-use your application should be below data model / card change ....
Thanks, Dave
Files starting with a lower-case letter are the object attributes. Upper-case files are for raw objects (eg. the certificate).
For example: C0 - Raw certificate 0 c0 - Certificate 0's attributes k0 - Key 0's attributes
The object's attributes file has a 7-byte header which is just used to tell the size of the data in the file:
1 byte - Object type (not currently used) 2 bytes - ??? not used 2 bytes - Object ID that this attribute file goes with (not used) 2 bytes - Size of all remaining data (ie. all the attributes)
The remaining data consists of TLV's:
4 bytes - CK_ATTRIBUTE_TYPE 2 bytes - Attribute length bytes - Attribute data 4 bytes - CK_ATTRIBUTE_TYPE 2 bytes - Attribute length bytes - Attribute data
Begin forwarded message:
From: Vinnie Moscaritolo <[EMAIL PROTECTED]> Date: May 18, 2004 2:22:05 PM CDT To: [email protected] Subject: [Muscle] re: X509Certificate (and PGP certs) on Muscle Tokens Reply-To: MUSCLE <[email protected]>
some notes on how the objects on card are managed. -----------
A muscle token consists of keys and objects. A token can have up to
16 keys and up to 8 PINS. Each key is either a public or private key,
and they are typically adjacent to each other, for example Key 0 might be
an RSA Private and Key 1 the corresponding RSA Public key.
It is also possible to have up 9 PINS on a token. Typically PIN 0 is
considered to be the Security Officer PIN, and is required for card
formatting, etc. PIN 1 - 4 are user PINS and can be mapped to any of
the keys. PIN 5-8 are used for challenge/response Key authentication,
and are not supported by this module.
A token can a number of objects on it. In the MUSCLE framework, Objects
are typically a form of generic container which have an ID which consist of
from 2 - 64 characters. Since there is no formal written spec for how
objects formatted, here is the the method used by the Muscle PKCS-11
module:
Objects can be in two forms. Containers and Attributes. Containers
are identified by uppercase first character and attributes are reflected
by lowercase. for example 'O1' is the object and 'o1' are the attributes.
Keys are described by special attributes that begin with 'k' for example the attributes for Key 0 would be 'k0' .. There is no uppercase K object.
Attributes are represented by a flattened form of PKCS-11 data. The format for this data is as follows:
Offset Bytes Description [0] 1 Object Type (always 0) [1] 2 Object ID (for example 'O1') [3] 2 Next ID ( not supported) [5] 2 Data Length [7] .... N items of flattened PKCS11 Data
The PKCS-11 data can be of the form
Boolean Bytes Description ------------------------------------------- 4 PKCS-11 CK_ATTRIBUTE_TYPE (boolean) 2 Data Length (1) 1 Boolean Value (1 or 0)
Numeric Bytes Description ------------------------------------------- 4 PKCS-11 CK_ATTRIBUTE_TYPE (Numeric) 2 Data Length (4) 4 Numeric Value
Data Bytes Description ------------------------------------------- 4 PKCS-11 CK_ATTRIBUTE_TYPE (data) 2 Data Length (n) n Value
---------------------------------------------------------------------- --
Note that the CKA_ID field is intended to distinguish among multiple keys.
In the case of public and private keys, this field assists in handling
multiple keys held by the same subject; the key identifier for a public
key and its corresponding private key should be the same. The key identifier
should also be the same as for the corresponding certificate, if one exists.
For PGP keys CKA_ID must be at least 8 bytes and these bytes must be a KeyId of the key. X.509 certificate(s) and a keypair must have identical CKA_IDs
Given this system, this is what we expect to find on a Token:
Keys: - key attributes 'k0' - 'kF' key_obj_id[1] = keyNum > 9 ? 'A' + keyNum : '0' + keyNum;
Keys (attributes) CKA_CLASS CKO_PUBLIC_KEY / CKO_PRIVATE_KEY CKA_KEY_TYPE CKK_RSA CKA_ID (could be PGP keyID ) CKA_LABEL "PGP.Private.Key" or "PGP.Public.Key"
----------------------------- Objects:
if (!islower(objectInfo.objectID[0])) look for attributes in tolower()
Public x509 certs (attributes)
CKA_CERTIFICATE_TYPE CKC_X_509 CKA_CLASS CKO_CERTIFICATE CKA_ID links with 'k' object
Object Value => x.509 cert
-----------------------------
PGP Public Key Data (attributes)
CKA_CLASS CKO_DATA CKA_APPLICATION "PGP" CKA_PRIVATE FALSE CKA_TOKEN TRUE CKA_LABEL PGP.Key.Data.0x5C3E5AAD2836C3BF
Object Value => PGP data stub (parse label for keyID to link to)
-----------------------------
for example on a CAC card you will see the following:
ID Size READ WRITE DELETE ----- ----- ------ ------ ------ C3 672 ALWAYS NEVER NEVER C5 672 ALWAYS NEVER NEVER C7 641 ALWAYS NEVER NEVER c7 48 ALWAYS NEVER NEVER c3 45 ALWAYS NEVER NEVER c5 45 ALWAYS NEVER NEVER k7 245 ALWAYS NEVER NEVER k3 245 ALWAYS NEVER NEVER k5 245 ALWAYS NEVER NEVER (some other stuff for PINS )
MSCListKeys() Key Type Bits mode dir READ WRITE USE --- -------------- ---- ---- ---- ------ ----- ------ 3 RSA Private 1024 0001 ---d NEVER NEVER PIN #1 5 RSA Private 1024 0001 s--- NEVER NEVER PIN #1 7 RSA Private 1024 0001 s--- NEVER NEVER PIN #1
c7 48 Bytes - p11 data CKA_CERTIFICATE_TYPE ( 4) : 0: 0000 0000 .... CKA_CLASS ( 4) : 0: 0100 0000 .... CKA_LABEL ( 8) : 0: 4964 656E 7469 7479 Identity CKA_ID ( 1) : 0: 07 . ----------
c3 45 Bytes - p11 data CKA_CERTIFICATE_TYPE ( 4) : 0: 0000 0000 .... CKA_CLASS ( 4) : 0: 0100 0000 .... CKA_LABEL ( 5) : 0: 456D 6169 6C Email CKA_ID ( 1) : 0: 03 . ----------
c5 45 Bytes - p11 data CKA_CERTIFICATE_TYPE ( 4) : 0: 0000 0000 .... CKA_CLASS ( 4) : 0: 0100 0000 .... CKA_LABEL ( 5) : 0: 456D 6169 6C Email CKA_ID ( 1) : 0: 05 . ----------
k7 245 Bytes - p11 data CKA_CLASS ( 4) : 0: 0300 0000 .... CKA_ID ( 1) : 0: 07 . CKA_EXTRACTABLE ( 1) : 0: 00 . CKA_SIGN_RECOVER ( 1) : 0: 00 . CKA_DERIVE ( 1) : 0: 00 . CKA_MODIFIABLE ( 1) : 0: 00 . CKA_UNWRAP ( 1) : 0: 01 . CKA_DECRYPT ( 1) : 0: 01 . CKA_PRIVATE ( 1) : 0: 01 . CKA_SIGN ( 1) : 0: 01 . CKA_NEVER_EXTRACTABLE ( 1) : 0: 01 . CKA_ALWAYS_SENSITIVE ( 1) : 0: 01 . CKA_SENSITIVE ( 1) : 0: 01 . CKA_KEY_TYPE ( 4) : 0: 0000 0000 .... CKA_MODULUS (128) : 0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 16: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 32: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 48: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 64: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 80: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 96: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 112: 0000 0000 0000 0000 0000 0000 0000 0000 ................ ----------
k3 245 Bytes - p11 data CKA_CLASS ( 4) : 0: 0300 0000 .... CKA_ID ( 1) : 0: 03 . CKA_EXTRACTABLE ( 1) : 0: 00 . CKA_SIGN_RECOVER ( 1) : 0: 00 . CKA_DERIVE ( 1) : 0: 00 . CKA_MODIFIABLE ( 1) : 0: 00 . CKA_UNWRAP ( 1) : 0: 01 . CKA_DECRYPT ( 1) : 0: 01 . CKA_PRIVATE ( 1) : 0: 01 . CKA_SIGN ( 1) : 0: 01 . CKA_NEVER_EXTRACTABLE ( 1) : 0: 01 . CKA_ALWAYS_SENSITIVE ( 1) : 0: 01 . CKA_SENSITIVE ( 1) : 0: 01 . CKA_KEY_TYPE ( 4) : 0: 0000 0000 .... CKA_MODULUS (128) : 0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 16: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 32: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 48: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 64: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 80: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 96: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 112: 0000 0000 0000 0000 0000 0000 0000 0000 ................ ----------
k5 245 Bytes - p11 data CKA_CLASS ( 4) : 0: 0300 0000 .... CKA_ID ( 1) : 0: 05 . CKA_EXTRACTABLE ( 1) : 0: 00 . CKA_SIGN_RECOVER ( 1) : 0: 00 . CKA_DERIVE ( 1) : 0: 00 . CKA_MODIFIABLE ( 1) : 0: 00 . CKA_UNWRAP ( 1) : 0: 01 . CKA_DECRYPT ( 1) : 0: 01 . CKA_PRIVATE ( 1) : 0: 01 . CKA_SIGN ( 1) : 0: 01 . CKA_NEVER_EXTRACTABLE ( 1) : 0: 01 . CKA_ALWAYS_SENSITIVE ( 1) : 0: 01 . CKA_SENSITIVE ( 1) : 0: 01 . CKA_KEY_TYPE ( 4) : 0: 0000 0000 .... CKA_MODULUS (128) : 0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 16: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 32: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 48: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 64: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 80: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 96: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 112: 0000 0000 0000 0000 0000 0000 0000 0000 ................ ----------
CAC Notes: 1) C3, C5, C7 will be the approp x.509 certs
2) you will have to get the CKA_MODULUS from the certs, since the k3,k5 and k7 objects will read zero...
3) CKA_CLASS is byte wrong endian on CAC cards it seems, something to do with Mozilla bug.. ------------
-- Vinnie Moscaritolo ITCB-IMSH PGP: 3F903472C3AF622D5D918D9BD8B100090B3EF042 -------------------------------------------------------
"When the pin is pulled, Mr. Grenade is not our friend." - USMC training bulletin.
_______________________________________________ Muscle mailing list [email protected] http://lists.drizzle.com/mailman/listinfo/muscle
------------------------------------------------------------------------ ------------
David Corcoran [EMAIL PROTECTED]
Identity Alliance http://www.identityalliance.com
phone: 260-488-3099 fax: 260-488-2455
Smart Cards, Biometrics, Training, Identity Management
------------------------------------------------------------------------ -------------
_______________________________________________ Muscle mailing list [email protected] http://lists.drizzle.com/mailman/listinfo/muscle
