Re: PKCS#11: C_Sign provides invalid signature

2010-10-16 Thread Nelson B Bolyard
On 2010-10-16 11:39 PDT, Matej Kurpel wrote:
>   On 16. 10. 2010 18:33, Nelson B Bolyard wrote:

>> The SignData method you're trying to use does all the above steps.
>> It wants the input to step 1.  Since you're implementing CKM_RSA_PKCS,
>> the data you're given is the input to step 3, the output from step 2.
>> You can deconstruct it and obtain from it the output from step 1, [...]

> Thank you, Nelson, it works now. I used the SignHash method instead, 
> with the OID string "1.3.14.3.2.26", which means SHA1. And I took just 
> the last 20 bytes of the provided data to sign - which is the hash.

You should not assume that the DigestInfo you're given will always contain
a SHA1 hash.  It may contain other hashes from other algorithms, of other
lengths.  It will always contain the proper OID string for the hash it has
used.  So, you should parse the DigestInfo you're given as input.  Take it
apart.  Pull out the OID string and the hash string using the explicit
lengths encoded in the DigestInfo, then pass those to SignHash.  Parsing
the DigestInfo is very straightforward.  I'm sure you can figure it out.

-- 
/Nelson Bolyard
-- 
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto


Re: PKCS#11: C_Sign provides invalid signature

2010-10-16 Thread Matej Kurpel

 On 16. 10. 2010 18:33, Nelson B Bolyard wrote:

On 2010-10-16 06:25 PDT, Matej Kurpel wrote:

   Hello,
I am developing a PKCS#11 module to be used with Thunderbird. However, I
have trouble providing a valid signature for e-mails. The mechanism used
is CKM_RSA_PKCS and I have a 1024bit private key along with the
certificate, stored on the token. The signature is generated in a C#
.NET CF program running on the device, using this piece of code:

RSACryptoServiceProvider rsa =
PKCS11Library.TryLoadPK(Encoding.ASCII.GetString(keyPath, 0,
keyPath.Length), out keyRawData); // this returns a valid
RSACryptoServiceProvider instance
signature = rsa.SignData(data, new SHA1CryptoServiceProvider()); //signs
the data we need

I am not sure about the second parameter of the rsa.SignData method -
the documentation says it is of type "object" and it's the mechanism to
be used to sign the data. I cannot think of any more appropriate object
to be passed there than SHA1CryptoServiceProvider.

This isn't really the place to come for advice about C# crypto ... but ...
the SignData method provides the wrong level of functionality for
CKM_RSA_PKCS.

The entire RSA signature creation process usually includes these steps:
   1) Choose a hash algorithm (e.g. SHA-something or MD5), get the OID
  string (number) value that identifies that algorithm, and use that
  algorithm to hash all the data to be signed.
   2) Construct an ASN.1 DER formatted buffer called a "DigestInfo" using
  that OID string and that hash value.
   3) Construct a PKCS#1 formatted buffer (either v 1.5 or v2.0) from
  that DER formatted buffer.
   4) Perform an RSA private key operation on that PKCS#1 formatted buffer.

In some applications, steps 2 and/or 3 are modified, and custom buffer
formats are used instead of the pure DigestInfo and/or PKCS#1 formats.

The CKM_RSA_PKCS mechanism you're attempting to implement does only
the last two of those steps.  It treats the input it is given as a
DigestInfo.  It then does the PKCS#1 formatting according to PKCS#1
version 1.5.  This gives its user the flexibility to implement the
normal DigestInfo buffer format, or any other custom format.

PKCS#1 Version 2.0 formatting is incompatible with CKM_RSA_PKCS.
PKCS#1 Version 2.0 formatting is done by another PKCS#11 mechanism, namely
CKM_RSA_PKCS_OAEP.

The SignData method you're trying to use does all the above steps.
It wants the input to step 1.  Since you're implementing CKM_RSA_PKCS,
the data you're given is the input to step 3, the output from step 2.
You can deconstruct it and obtain from it the output from step 1, but
you cannot go back to having the input to step 1, because the hash is
irreversible.  So, I think you cannot use SignData to implement CKM_RSA_PKCS.

C#'s RSACryptoServiceProvider class also features a SignHash method that
does the last three of those steps.  It expects to receive, as input, the
hash value and the OID string.  It constructs the DigestInfo and the
PKCS#1 buffer and does the RSA private key operation.  Whether it formats
the PKCS#1 buffer according PKCS#1 version 1.5 or version 2.0 is unknown
to me.  I couldn't find any reference to PKCS in MSDN's C# documentation.

Thank you, Nelson, it works now. I used the SignHash method instead, 
with the OID string "1.3.14.3.2.26", which means SHA1. And I took just 
the last 20 bytes of the provided data to sign - which is the hash.


M. Kurpel
--
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto


Re: PKCS#11: C_Sign provides invalid signature

2010-10-16 Thread Nelson B Bolyard
On 2010-10-16 06:25 PDT, Matej Kurpel wrote:
>   Hello,
> I am developing a PKCS#11 module to be used with Thunderbird. However, I 
> have trouble providing a valid signature for e-mails. The mechanism used 
> is CKM_RSA_PKCS and I have a 1024bit private key along with the 
> certificate, stored on the token. The signature is generated in a C# 
> .NET CF program running on the device, using this piece of code:
> 
> RSACryptoServiceProvider rsa = 
> PKCS11Library.TryLoadPK(Encoding.ASCII.GetString(keyPath, 0, 
> keyPath.Length), out keyRawData); // this returns a valid 
> RSACryptoServiceProvider instance
> signature = rsa.SignData(data, new SHA1CryptoServiceProvider()); //signs 
> the data we need
> 
> I am not sure about the second parameter of the rsa.SignData method - 
> the documentation says it is of type "object" and it's the mechanism to 
> be used to sign the data. I cannot think of any more appropriate object 
> to be passed there than SHA1CryptoServiceProvider.

This isn't really the place to come for advice about C# crypto ... but ...
the SignData method provides the wrong level of functionality for
CKM_RSA_PKCS.

The entire RSA signature creation process usually includes these steps:
  1) Choose a hash algorithm (e.g. SHA-something or MD5), get the OID
 string (number) value that identifies that algorithm, and use that
 algorithm to hash all the data to be signed.
  2) Construct an ASN.1 DER formatted buffer called a "DigestInfo" using
 that OID string and that hash value.
  3) Construct a PKCS#1 formatted buffer (either v 1.5 or v2.0) from
 that DER formatted buffer.
  4) Perform an RSA private key operation on that PKCS#1 formatted buffer.

In some applications, steps 2 and/or 3 are modified, and custom buffer
formats are used instead of the pure DigestInfo and/or PKCS#1 formats.

The CKM_RSA_PKCS mechanism you're attempting to implement does only
the last two of those steps.  It treats the input it is given as a
DigestInfo.  It then does the PKCS#1 formatting according to PKCS#1
version 1.5.  This gives its user the flexibility to implement the
normal DigestInfo buffer format, or any other custom format.

PKCS#1 Version 2.0 formatting is incompatible with CKM_RSA_PKCS.
PKCS#1 Version 2.0 formatting is done by another PKCS#11 mechanism, namely
CKM_RSA_PKCS_OAEP.

The SignData method you're trying to use does all the above steps.
It wants the input to step 1.  Since you're implementing CKM_RSA_PKCS,
the data you're given is the input to step 3, the output from step 2.
You can deconstruct it and obtain from it the output from step 1, but
you cannot go back to having the input to step 1, because the hash is
irreversible.  So, I think you cannot use SignData to implement CKM_RSA_PKCS.

C#'s RSACryptoServiceProvider class also features a SignHash method that
does the last three of those steps.  It expects to receive, as input, the
hash value and the OID string.  It constructs the DigestInfo and the
PKCS#1 buffer and does the RSA private key operation.  Whether it formats
the PKCS#1 buffer according PKCS#1 version 1.5 or version 2.0 is unknown
to me.  I couldn't find any reference to PKCS in MSDN's C# documentation.

-- 
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto


PKCS#11: C_Sign provides invalid signature

2010-10-16 Thread Matej Kurpel

 Hello,
I am developing a PKCS#11 module to be used with Thunderbird. However, I 
have trouble providing a valid signature for e-mails. The mechanism used 
is CKM_RSA_PKCS and I have a 1024bit private key along with the 
certificate, stored on the token. The signature is generated in a C# 
.NET CF program running on the device, using this piece of code:


RSACryptoServiceProvider rsa = 
PKCS11Library.TryLoadPK(Encoding.ASCII.GetString(keyPath, 0, 
keyPath.Length), out keyRawData); // this returns a valid 
RSACryptoServiceProvider instance
signature = rsa.SignData(data, new SHA1CryptoServiceProvider()); //signs 
the data we need


I am not sure about the second parameter of the rsa.SignData method - 
the documentation says it is of type "object" and it's the mechanism to 
be used to sign the data. I cannot think of any more appropriate object 
to be passed there than SHA1CryptoServiceProvider.


Now, the problem is that the signed e-mail is sent correctly but after 
receiving it, Thunderbird states that the signature is invalid. My 
question is, is there any format NSS (Thunderbird) needs the signature 
in? Does the signature I am providing, look properly at a first glance? 
(Please look at line 45 in the pkcs11-spy log I am attaching).


 PKCS11 SPY LOG BEGIN 


32: C_GetAttributeValue
[in] hSession = 0x1
[in] hObject = 0x1
[in] pTemplate[2]:
CKA_IDrequested with 0 buffer
CKA_CLASS requested with 0 buffer
[out] pTemplate[2]:
CKA_IDhas size 4
CKA_CLASS has size 4
Returned:  0 CKR_OK


33: C_GetAttributeValue
[in] hSession = 0x1
[in] hObject = 0x1
[in] pTemplate[2]:
CKA_IDrequested with 4 buffer
CKA_CLASS requested with 4 buffer
[out] pTemplate[2]:
CKA_ID[size : 0x4 (4)]
0100
CKA_CLASS CKO_CERTIFICATE
Returned:  0 CKR_OK


34: C_FindObjectsInit
[in] hSession = 0x1
[in] pTemplate[2]:
CKA_ID[size : 0x4 (4)]
0100
CKA_CLASS CKO_PRIVATE_KEY
Returned:  0 CKR_OK


35: C_FindObjects
[in] hSession = 0x1
[in] ulMaxObjectCount = 0x1
[out] ulObjectCount = 0x1
Object 2 Matches
Returned:  0 CKR_OK


36: C_FindObjectsFinal
[in] hSession = 0x1
Returned:  0 CKR_OK


37: C_GetAttributeValue
[in] hSession = 0x1
[in] hObject = 0x2
[in] pTemplate[1]:
CKA_KEY_TYPE  requested with 4 buffer
[out] pTemplate[1]:
CKA_KEY_TYPE  CKK_RSA
Returned:  0 CKR_OK


38: C_GetAttributeValue
[in] hSession = 0x1
[in] hObject = 0x2
[in] pTemplate[1]:
CKA_TOKEN requested with 1 buffer
[out] pTemplate[1]:
CKA_TOKEN True
Returned:  0 CKR_OK


39: C_GetAttributeValue
[in] hSession = 0x1
[in] hObject = 0x2
[in] pTemplate[1]:
CKA_PRIVATE   requested with 1 buffer
[out] pTemplate[1]:
CKA_PRIVATE   True
Returned:  0 CKR_OK


40: C_GetAttributeValue
[in] hSession = 0x1
[in] hObject = 0x2
[in] pTemplate[1]:
CKA_MODULUS   requested with 0 buffer
[out] pTemplate[1]:
CKA_MODULUS   has size 128
Returned:  0 CKR_OK


41: C_GetAttributeValue
[in] hSession = 0x1
[in] hObject = 0x2
[in] pTemplate[1]:
CKA_MODULUS   requested with 128 buffer
[out] pTemplate[1]:
CKA_MODULUS   [size : 0x80 (128)]
D0B54A0E 53C59293 278EE27A 928C30CB 4A1942F6 DE32B8A4 951196DF 53FE8469
7225D5B0 98421497 C7C70428 2468A022 C17B0E51 E17B86C4 E0624BED 398FCDCD
422F789A 9518E4D4 DC07DA20 186BD121 2B80725E 8AE34A68 78FBC43E 6F3A2A95
DC808706 01C8A576 B5A072E1 2F773240 F60AF083 5021112A E9F0CB7F 98A7EEC5
Returned:  0 CKR_OK


42: C_GetAttributeValue
[in] hSession = 0x1
[in] hObject = 0x2
[in] pTemplate[1]:
CKA_PRIVATE   requested with 1 buffer
[out] pTemplate[1]:
CKA_PRIVATE   True
Returned:  0 CKR_OK


43: C_OpenSession
[in] slotID = 0x0
[in] flags = 0x4
pApplication=068DE800
Notify=5F8B5E19
[out] *phSession = 0x2
Returned:  0 CKR_OK


44: C_SignInit
[in] hSession = 0x2
pMechanism->type=CKM_RSA_PKCS
[in] hKey = 0x2
Returned:  0 CKR_OK


45: C_Sign
[in] hSession = 0x2
[in] pData[ulDataLen] [size : 0x23 (35)]
30213009 06052B0E 03021A05 0004149A E91D78EE 1FDC8F4F A65E41A2 1263BF31
94C4D2
[out] pSignature[*pulSignatureLen] [size : 0x80 (128)]
63334030 9439D903 9645AC11 C1C05136 0B17A571 16E3F223 06CA4941 CB0721E5
194CF829 43DF0DE9 AB6BD5DF 051A8906 1D974171 6879468E 1F043C4B 7763E607
D0163299 54AA23B4 4BD221B7 B8F1F880 23D7E032 2AB6C7D9 18C29AEF 23603C08
E91BE397 303271E4 1850AC57 B53CD457 D10056DE 3C7CCB0F 99AFFF51 86CC3E28
Returned:  0 CKR_OK


46: C_CloseSession
[in] hSession = 0x2
Returned:  0 CKR_OK


47: C_GetAttributeValue
[in] hSession = 0x1
[in] hObject = 0x1
[in] pTemplate[2]:
CKA_IDrequested with 0 buffer
CKA_CLASS requested with 0 buffer
[out] pTemplate[2]:
CKA_IDhas size 4
CKA_CLASS