Thanks Michael.
Q#3 (continue # from previous emails):
I tried to dig through the old emails, but I could not find the "Use
Case" example for CKM_SEAL_KEY.
But, here is a one example that I can think of (if I understand this
correctly):
Backing up a wrapped RSA private key, a password on a USB stick for
temporary use, and seal it with this CKM_SEAL_KEY mechanism.
This wrapped RSA private key is by no means to be exported to
anywhere outside of the token.
Best,
Oscar
On 07/ 2/13 06:39 PM, Michael StJohns wrote:
On 7/2/2013 6:04 PM, Oscar K So Jr.
wrote:
Thanks Michael.
"Are you suggesting that I should add an unwrapping example as
well?"
I am trying to understand the whole thing completely. We can
wait for other people's opinion on this.
So, sorry, let me ask more questions, for:
rv = C_UnwrapKey(
hSession,
CKM_SEAL_KEY,
hUnwrappingKey,
pWrappedKey,
ulWrappedKeyLen,
NULL_PTR, /* pTemplate */
0, /* ulAttributeCount */
&hKey /* handle to the unwrapped key blob */
);
Q#1:
You said once the PKCS #11 library has been C_Finalized, it can
be re-find with "CKA_OBJECT_CLASS, CKA_LABEL, CKA_ID,
CKA_CHECK_VALUE, CKA_KEY_TYPE",
Since pTemplate==NULL_PTR is the argument, I am guessing that
there must be a pTemplate stored somewhere in order to extract
the above mentioned attributes from the blob, correct ? Or, the
pTemplate itself is stored inside the blob too (if that's the
case, that's COOL too, it will work!!!) ?
But, you will need CKA_UNWRAP_TEMPLATE to extract the blob.
No. Using the handle you get from C_UnwrapKey, use
C_GetAttributeValue to get the values of CKA_OBJECT_CLASS,
CKA_LABEL, CKA_ID etc - sufficient values to ensure you can
identify the key. (If the proposal for CKA_PUBLIC_KEY_INFO
passes, that would be sufficient data to identify a private key
for example).
The values from that query can be stored somewhere off the token,
and then used with C_FindObjects to find the key.
Or get the attributes from the original key before you wrap it and
delete it and store it with the saved blob.
Alternatively (and possibly more easily), just delete the key
after you're done with it and restore it from the sealed blob the
next time you need to use it. The actual management of whether
the key is in the token or just in the sealed blob or both is left
up to the client.
The wrapped blob doesn't actually need to store PKCS11
CK_ATTRIBUTES, it just needs to store the internal representation
of the the key or object material in an encrypted form in a manner
that the token can easily restore it. E.g. the format of the data
that is wrapped need not have any PKCS11 semantics associated with
it - but the data once unwrapped and installed in the token gets
accessed via PKCS11 and gets PKCS11 semantics applied to it (or
derived from it).
Q#2:
And, if there is a pTemplate stored somewhere, it must be
created during C_WrapKey, right ? Or, during C_GenerateKey or
C_GenerateKeyPairs or, based on some security policy set in Key
Management Server's Key Wrapping Specification (KMIP 2.1.6) ? I
think that's the best time to create and store such pTemplate.
Also, you wrote that "this mechanism DOES NOT support unwrapping
keys on any token besides the token from which the key was
originally wrapped."
There's about 2-4 questions there I think.
2.1 - there's no template stored anywhere. Think of the process
for C_WrapKey this way :
a) Marshall the internal key data into a byte array (e.g.
convert all the internal structures that represent the key into a
stream of bytes and that stream includes - in a vendor specific
way - the secret part of the key material, some indication of what
type of key it is, the various boolean attributes that control
access, things like the labels, etc. )
b) encrypt the marshalled data using the vendor specific
encryption mechanism and the specified wrapping key and produce
the opaque blob.
The unwrapping is the reverse of this - decrypt and unmarshall.
(Hmm.. let's be even more specific - an AES key maybe.
struct {
uint32 flags; // this is where all the boolean values are
represented such as CKA_ENCRYPT etc
char[32] label;
uchar labelLength;
attribute *attrPtr; // pointer to a linked list of attributes
uchar *keyData;
uchar keyDataLength;
}
The vendor would might marshal this by emitting a 32 bit type code
(e.g. AES key), the 32 bits of flag, the 32 octets of label, the 1
octet of labelLength, a 16 bit count of attributes, the
de-referenced attribute structures and lengths, the key data
length, and the actual key data. Or any of a number of similar
schemes. There is no requirement that the internal representation
bear any strong resemblance to the PKCS11 abstraction.
2.2 The last question - basically, since the seal key is generated
on the token, never leaves the token and is never used for any
other purpose except for use with this mechanism - the only way
the unwrapping can succeed is on the token that originally wrapped
the key.
Later, Mike
Thanks,
Oscar
On 07/ 2/13 01:09 PM, Michael StJohns wrote:
On 7/2/2013 1:11 PM, Oscar K So Jr. wrote:
Thanks Michael.
You are suggesting this usage:
rv = C_UnwrapKey(
hSession,
CKM_SEAL_KEY,
hUnwrappingKey,
pWrappedKey,
ulWrappedKeyLen,
NULL_PTR, /* pTemplate */
0, /* ulAttributeCount */
&hKey /* handle to the unwrapped key blob */
);
Pretty much. Are you suggesting that I should add an
unwrapping example as well? I didn't think it was necessary,
but it's pretty easy to add.
And, any application calling this function with CKA_SEAL_KEY
should NOT receive error codes such as:
CKR_ARGUMENTS_BAD
CKR_TEMPLATE_INCOMPLETE,
CKR_TEMPLATE_INCONSISTENT
?
If that's the case, I think the above will work!
Right. You can get CKR_ARGUMENTS_BAD if you've got no other
applicable code, but the template errors shouldn't occur.
Mostly if you try and unwrap a badly wrapped key you're going
to get a CKR_WRAPPED_KEY_INVALID error or something similar.
Anything except CKR_OK means you weren't able to unwrap and
re-create a key.
------------------------------------------------------------------------------------------------------------------
But, say, once we call C_Finalize, and how do we
C_FindObjects of that hKey later ?
If the unwrapped key is a token key (CKA_TOKEN = TRUE - and
that's as it's marked in the opaque encrypted, integrity
protected blob) it gets stored on the token by C_UnwrapKey and
can be re-found after a C_Finalize using C_FindObject et al.
in a new session using the various attributes of that key
(generally CKA_OBJECT_CLASS, CKA_LABEL, CKA_ID,
CKA_CHECK_VALUE, CKA_KEY_TYPE et al) that were also used to
mark the object inside the encrypted blob. You may already
know them (because you are the one that stored the blob), or
you can recover them from the key object via
C_GetAttributeValue at a later time.
If its a session key, the key isn't recoverable once the
session ends.
Mike
Best,
Oscar
On 07/ 2/13 08:47 AM, Michael StJohns wrote:
On 7/2/2013 2:25 AM, Oscar So wrote:
Michael,
For your proposal on CKM_SEAL_KEY, at the 9th paragraph
you wrote:
"When this mechanism is used with C_UnwrapKey,
ulAttributeCount should be 0."
Could you explain more about this ?
Why does it have to be zero ?
Thanks,
Oscar
Hi Oscar -
The general contract of this mechanism is that what is
wrapped is the internal, vendor-specific data related to
the object being wrapped and that you get exactly the same
thing back when you do the unwrap operation. E.g. if K is
all the data that describes a key in a vendor specific way
then the following is true for this mechanism:
K' == unwrap(wrap(K)) == K
where K' is the unwrapped key. K is indistinguishable
from K' (key data, attributes etc) except for the handle
of the key.
Normally with a C_UnwrapKey the template provides all (or
most of) the information about the key material you're
unwrapping, possibly along with the CKA_UNWRAP_TEMPLATE on
the unwrapping key. In the case of a private key some
attributes (should) get set from the PKCS8 structure that
contains the private key. So you possibly have three
different sources for any given attribute. AND you have
to get the combination of attributes correct for any given
wrapped key blob.
For this mechanism, the only source of attributes is the
opaque blob that you wrapped. You don't need to specify
any attributes on unwrapping because the blob carries all
the information necessary regardless of the underlying
type of the key or object. I briefly considered allowing
mix-ins for other attributes (via the C_UnwrapKey call and
via a CKA_UNWRAP_TEMPLATE on the unwrapping key), but came
to the conclusion that it would violate the general goal
of the mechanism and possibly provide some paths to
manipulate the policy markers associated with PKCS11.
Is there a use case you can think of where having
attributes mixed in on unwrap makes sense and doesn't
weaken the security goals?
Mike
--
Best,
Oscar
--
Best,
Oscar
|