Minidriver assume hexstring encoding for card serial number

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Minidriver assume hexstring encoding for card serial number

Andreas Schwier (ML)
Hi everyone,

we've come across an issue with the minidriver which assumes the card
serial number to be a hex string.

In our card the serial number is a string composed of ASCII characters.
This works well with pkcs15-tool and the PKCS#11 library, however it
fails with the current minidriver when it tries to convert the hex
string into binary data for the cardid file.

Neither in PKCS#11 spec nor in ISO 7816-15 I can find a definition for
encoding the serial number as hex string.

I therefore propose to change the code in minidriver.c to do the following:

1. try parsing tokeninfo->serial_number as hex string
2. if that fails copy serial_number as is with the length being the
length of the ASCII encoded string

This should not interfere with current card drivers which all use a hex
string as serial number.

Any objections ?

Andreas

--

    ---------    CardContact Software & System Consulting
   |.##> <##.|   Andreas Schwier
   |#       #|   Schülerweg 38
   |#       #|   32429 Minden, Germany
   |'##> <##'|   Phone +49 171 8334920
    ---------    http://www.cardcontact.de
                 http://www.tscons.de
                 http://www.openscdp.org

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Minidriver assume hexstring encoding for card serial number

Douglas E. Engert


On 8/22/2012 5:28 AM, Andreas Schwier (ML) wrote:

> Hi everyone,
>
> we've come across an issue with the minidriver which assumes the card
> serial number to be a hex string.
>
> In our card the serial number is a string composed of ASCII characters.
> This works well with pkcs15-tool and the PKCS#11 library, however it
> fails with the current minidriver when it tries to convert the hex
> string into binary data for the cardid file.
>
> Neither in PKCS#11 spec nor in ISO 7816-15 I can find a definition for
> encoding the serial number as hex string.

The minidriver does not use the PKCS#11 standards, it is the Microsoft
definition of what it expects in the cardid file that counts.

http://www.microsoft.com/whdc/device/input/smartcard/sc-minidriver.mspx

Section 5.4.1 says:

  "The logical name for this file is “CardId”. It is in the root directory."

  "The file is organized as a 16-byte array. It should be treated as opaque binary data."

  "This value is assigned by Microsoft software to assure that a unique value is
   generated for the card. It is unrelated to the serial number that may or may not
   be assigned to the card during manufacture."

In other places it calls it as a GUID.

This also means that when displayed, it maybe displayed as a GUID as hex digits
with "{", "}" "," and "-"  added for readability, and some bytes reversed in little
endian machines. So it may not be recognizable as your serial number.

That said, since the minidriver is emulating a card that should have a cardid file,
the data to populate the emulated cardid file has to come from the card and be the same
at every use,  and unique across all cards not just one site or one card vendor.

The value or its derivatives are stored in the certificate store and used
to associate cards with data previously cached.

>
> I therefore propose to change the code in minidriver.c to do the following:
>
> 1. try parsing tokeninfo->serial_number as hex string
> 2. if that fails copy serial_number as is with the length being the
> length of the ASCII encoded string

It must be 16 bytes.

>
> This should not interfere with current card drivers which all use a hex
> string as serial number.
>
> Any objections ?

If you can show that your method has enough uniqueness, to not cause problems
with other cards, then no.

>
> Andreas
>

--

  Douglas E. Engert  <[hidden email]>
  Argonne National Laboratory
  9700 South Cass Avenue
  Argonne, Illinois  60439
  (630) 252-5444


_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Minidriver assume hexstring encoding for card serial number

Andreas Schwier
Hi Douglas,

thanks for your infos.

The minidriver.c already ensures that the cardid file is always 16 byte.
It does this by repeating the token serial number until 16 bytes are filled.

We can ensure uniqueness of the serial number for our cards, but no
uniqueness among all other card vendors. There remains a (very) little
probability that a hexadecimal encoded serial number of another vendor's
card resembles one of our ASCII serial numbers.

Our serial numbers are based on the numbering scheme for machine
readable travel documents, a 2 digit country code followed by up to 9
ASCII digits (e.g. UTTM1234567 equals 5554544D313233343536375554544D31
in cardid).

Our proposed change (see [1]) will not alter the current behaviour with
existing cards. It will just allow a card that uses a ASCII serial
number to work as well.

An alternative approach - and probably more invasive - would be to use
the result of SC_CARDCTL_GET_SERIALNR in minidriver.c as input for the
cardid file. This way we could still have our human readable serial
number at the PKCS#11 und PKCS#15 level and a little more uniqueness in
the cardid file. This will however break existing installations, as the
content of the cardid file might change with the driver update.

Andreas

[1]
https://github.com/CardContact/OpenSC/commit/724cdd06e23ecd2e822bd1f138d9c3fbdafe9324

Am 22.08.2012 16:29, schrieb Douglas E. Engert:

>
> On 8/22/2012 5:28 AM, Andreas Schwier (ML) wrote:
>> Hi everyone,
>>
>> we've come across an issue with the minidriver which assumes the card
>> serial number to be a hex string.
>>
>> In our card the serial number is a string composed of ASCII characters.
>> This works well with pkcs15-tool and the PKCS#11 library, however it
>> fails with the current minidriver when it tries to convert the hex
>> string into binary data for the cardid file.
>>
>> Neither in PKCS#11 spec nor in ISO 7816-15 I can find a definition for
>> encoding the serial number as hex string.
> The minidriver does not use the PKCS#11 standards, it is the Microsoft
> definition of what it expects in the cardid file that counts.
>
> http://www.microsoft.com/whdc/device/input/smartcard/sc-minidriver.mspx
>
> Section 5.4.1 says:
>
>   "The logical name for this file is “CardId”. It is in the root directory."
>
>   "The file is organized as a 16-byte array. It should be treated as opaque binary data."
>
>   "This value is assigned by Microsoft software to assure that a unique value is
>    generated for the card. It is unrelated to the serial number that may or may not
>    be assigned to the card during manufacture."
>
> In other places it calls it as a GUID.
>
> This also means that when displayed, it maybe displayed as a GUID as hex digits
> with "{", "}" "," and "-"  added for readability, and some bytes reversed in little
> endian machines. So it may not be recognizable as your serial number.
>
> That said, since the minidriver is emulating a card that should have a cardid file,
> the data to populate the emulated cardid file has to come from the card and be the same
> at every use,  and unique across all cards not just one site or one card vendor.
>
> The value or its derivatives are stored in the certificate store and used
> to associate cards with data previously cached.
>
>> I therefore propose to change the code in minidriver.c to do the following:
>>
>> 1. try parsing tokeninfo->serial_number as hex string
>> 2. if that fails copy serial_number as is with the length being the
>> length of the ASCII encoded string
> It must be 16 bytes.
>
>> This should not interfere with current card drivers which all use a hex
>> string as serial number.
>>
>> Any objections ?
> If you can show that your method has enough uniqueness, to not cause problems
> with other cards, then no.
>
>> Andreas
>>


--

    ---------    CardContact Software & System Consulting
   |.##> <##.|   Andreas Schwier
   |#       #|   Schülerweg 38
   |#       #|   32429 Minden, Germany
   |'##> <##'|   Phone +49 171 8334920
    ---------    http://www.cardcontact.de
                 http://www.tscons.de
                 http://www.openscdp.org

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Minidriver assume hexstring encoding for card serial number

Douglas E. Engert


On 8/22/2012 10:09 AM, Andreas Schwier wrote:
> Hi Douglas,
>
> thanks for your infos.
>
> The minidriver.c already ensures that the cardid file is always 16 byte.
> It does this by repeating the token serial number until 16 bytes are filled.

Unfortunately that gives OpenbSC 16 bytes but does not improve the uniqunness.

Fortunately the uniqueness today only needs to extend over all the cards
as seen on a single machine which may be only a hand full. the cardid
is not sent to AD for example.  But it also means that if the certificates
or keys on a card are changed, the cardid should also change.

>
> We can ensure uniqueness of the serial number for our cards, but no
> uniqueness among all other card vendors. There remains a (very) little
> probability that a hexadecimal encoded serial number of another vendor's
> card resembles one of our ASCII serial numbers.
>
> Our serial numbers are based on the numbering scheme for machine
> readable travel documents, a 2 digit country code followed by up to 9
> ASCII digits (e.g. UTTM1234567 equals 5554544D313233343536375554544D31
> in cardid).

You did not say what was the minimum number of digits are, and
in you example the first 4 "ACSII digits" are letters not numbers that
introduce more uniqueness then numbers. Also for a single machine would
it always see the same country code?

If you have 9 ASCII characters that should introduce enough uniqueness
to avoid conflicts with your other cards and other vendors cards.

One point I am trying to make is the cardid value is not really seen
by the user, thus it does not have to be printable, and it could
hold more uniqueness then a printable string. But if there is not
enough unique data on the card to populate the cardid you have to use
whatever you have.

>
> Our proposed change (see [1]) will not alter the current behaviour with
> existing cards. It will just allow a card that uses a ASCII serial
> number to work as well.
>
> An alternative approach - and probably more invasive - would be to use
> the result of SC_CARDCTL_GET_SERIALNR in minidriver.c as input for the
> cardid file. This way we could still have our human readable serial
> number at the PKCS#11 und PKCS#15 level and a little more uniqueness in
> the cardid file.

On some cards whewre there is no serial readable form the card the
SC_CARDCTL_GET_SERIALNR does similar tricts to come up with a "serial number"
from what ever data it can use on the card.


> This will however break existing installations, as the
> content of the cardid file might change with the driver update.
>

Yes it might break existing installations, as it would look like  a new card
to the application, but with the same certificate on two cards. This could be
an issue if Windows searches the cert store for a certificate, then asks the
user to insert the matching card. i.e. the old card, not the new one.

As long as you have 6 digits or characters in your printable string that should
be fine.

> Andreas
>
> [1]
> https://github.com/CardContact/OpenSC/commit/724cdd06e23ecd2e822bd1f138d9c3fbdafe9324
>
> Am 22.08.2012 16:29, schrieb Douglas E. Engert:
>>
>> On 8/22/2012 5:28 AM, Andreas Schwier (ML) wrote:
>>> Hi everyone,
>>>
>>> we've come across an issue with the minidriver which assumes the card
>>> serial number to be a hex string.
>>>
>>> In our card the serial number is a string composed of ASCII characters.
>>> This works well with pkcs15-tool and the PKCS#11 library, however it
>>> fails with the current minidriver when it tries to convert the hex
>>> string into binary data for the cardid file.
>>>
>>> Neither in PKCS#11 spec nor in ISO 7816-15 I can find a definition for
>>> encoding the serial number as hex string.
>> The minidriver does not use the PKCS#11 standards, it is the Microsoft
>> definition of what it expects in the cardid file that counts.
>>
>> http://www.microsoft.com/whdc/device/input/smartcard/sc-minidriver.mspx
>>
>> Section 5.4.1 says:
>>
>>    "The logical name for this file is “CardId”. It is in the root directory."
>>
>>    "The file is organized as a 16-byte array. It should be treated as opaque binary data."
>>
>>    "This value is assigned by Microsoft software to assure that a unique value is
>>     generated for the card. It is unrelated to the serial number that may or may not
>>     be assigned to the card during manufacture."
>>
>> In other places it calls it as a GUID.
>>
>> This also means that when displayed, it maybe displayed as a GUID as hex digits
>> with "{", "}" "," and "-"  added for readability, and some bytes reversed in little
>> endian machines. So it may not be recognizable as your serial number.
>>
>> That said, since the minidriver is emulating a card that should have a cardid file,
>> the data to populate the emulated cardid file has to come from the card and be the same
>> at every use,  and unique across all cards not just one site or one card vendor.
>>
>> The value or its derivatives are stored in the certificate store and used
>> to associate cards with data previously cached.
>>
>>> I therefore propose to change the code in minidriver.c to do the following:
>>>
>>> 1. try parsing tokeninfo->serial_number as hex string
>>> 2. if that fails copy serial_number as is with the length being the
>>> length of the ASCII encoded string
>> It must be 16 bytes.
>>
>>> This should not interfere with current card drivers which all use a hex
>>> string as serial number.
>>>
>>> Any objections ?
>> If you can show that your method has enough uniqueness, to not cause problems
>> with other cards, then no.
>>
>>> Andreas
>>>
>
>

--

  Douglas E. Engert  <[hidden email]>
  Argonne National Laboratory
  9700 South Cass Avenue
  Argonne, Illinois  60439
  (630) 252-5444


_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Minidriver assume hexstring encoding for card serial number

Andreas Schwier (ML)
Hi Douglas,

see below.

Am 22.08.2012 18:00, schrieb Douglas E. Engert:

>
> On 8/22/2012 10:09 AM, Andreas Schwier wrote:
>> Hi Douglas,
>>
>> thanks for your infos.
>>
>> The minidriver.c already ensures that the cardid file is always 16 byte.
>> It does this by repeating the token serial number until 16 bytes are filled.
> Unfortunately that gives OpenbSC 16 bytes but does not improve the uniqunness.
>
> Fortunately the uniqueness today only needs to extend over all the cards
> as seen on a single machine which may be only a hand full. the cardid
> is not sent to AD for example.  But it also means that if the certificates
> or keys on a card are changed, the cardid should also change.
>
>> We can ensure uniqueness of the serial number for our cards, but no
>> uniqueness among all other card vendors. There remains a (very) little
>> probability that a hexadecimal encoded serial number of another vendor's
>> card resembles one of our ASCII serial numbers.
>>
>> Our serial numbers are based on the numbering scheme for machine
>> readable travel documents, a 2 digit country code followed by up to 9
>> ASCII digits (e.g. UTTM1234567 equals 5554544D313233343536375554544D31
>> in cardid).
> You did not say what was the minimum number of digits are, and
> in you example the first 4 "ACSII digits" are letters not numbers that
> introduce more uniqueness then numbers. Also for a single machine would
> it always see the same country code?
The serial number is always 11 characters (0-9, A-Z). The country code
is the country of the card issuer, within a country the card issuer gets
a 2-character prefix and will define the remaining 7 character.
>
> If you have 9 ASCII characters that should introduce enough uniqueness
> to avoid conflicts with your other cards and other vendors cards.
>
> One point I am trying to make is the cardid value is not really seen
> by the user, thus it does not have to be printable, and it could
> hold more uniqueness then a printable string. But if there is not
> enough unique data on the card to populate the cardid you have to use
> whatever you have.
Yes, I understand. I'm just concerned about the serial number visible to
the user at the PKCS#15 and PKCS#11 level. There it would be nice to see
the same serial number as the one printed on the card. My point is, that
currently the minidriver silently assumes that the
tokeninfo->serial_number contains a string with hexadecimal characters.

>
>> Our proposed change (see [1]) will not alter the current behaviour with
>> existing cards. It will just allow a card that uses a ASCII serial
>> number to work as well.
>>
>> An alternative approach - and probably more invasive - would be to use
>> the result of SC_CARDCTL_GET_SERIALNR in minidriver.c as input for the
>> cardid file. This way we could still have our human readable serial
>> number at the PKCS#11 und PKCS#15 level and a little more uniqueness in
>> the cardid file.
> On some cards whewre there is no serial readable form the card the
> SC_CARDCTL_GET_SERIALNR does similar tricts to come up with a "serial number"
> from what ever data it can use on the card.
>
>
>> This will however break existing installations, as the
>> content of the cardid file might change with the driver update.
>>
> Yes it might break existing installations, as it would look like  a new card
> to the application, but with the same certificate on two cards. This could be
> an issue if Windows searches the cert store for a certificate, then asks the
> user to insert the matching card. i.e. the old card, not the new one.
>
> As long as you have 6 digits or characters in your printable string that should
> be fine.
>
>> Andreas
>>
>> [1]
>> https://github.com/CardContact/OpenSC/commit/724cdd06e23ecd2e822bd1f138d9c3fbdafe9324
>>
>> Am 22.08.2012 16:29, schrieb Douglas E. Engert:
>>> On 8/22/2012 5:28 AM, Andreas Schwier (ML) wrote:
>>>> Hi everyone,
>>>>
>>>> we've come across an issue with the minidriver which assumes the card
>>>> serial number to be a hex string.
>>>>
>>>> In our card the serial number is a string composed of ASCII characters.
>>>> This works well with pkcs15-tool and the PKCS#11 library, however it
>>>> fails with the current minidriver when it tries to convert the hex
>>>> string into binary data for the cardid file.
>>>>
>>>> Neither in PKCS#11 spec nor in ISO 7816-15 I can find a definition for
>>>> encoding the serial number as hex string.
>>> The minidriver does not use the PKCS#11 standards, it is the Microsoft
>>> definition of what it expects in the cardid file that counts.
>>>
>>> http://www.microsoft.com/whdc/device/input/smartcard/sc-minidriver.mspx
>>>
>>> Section 5.4.1 says:
>>>
>>>    "The logical name for this file is “CardId”. It is in the root directory."
>>>
>>>    "The file is organized as a 16-byte array. It should be treated as opaque binary data."
>>>
>>>    "This value is assigned by Microsoft software to assure that a unique value is
>>>     generated for the card. It is unrelated to the serial number that may or may not
>>>     be assigned to the card during manufacture."
>>>
>>> In other places it calls it as a GUID.
>>>
>>> This also means that when displayed, it maybe displayed as a GUID as hex digits
>>> with "{", "}" "," and "-"  added for readability, and some bytes reversed in little
>>> endian machines. So it may not be recognizable as your serial number.
>>>
>>> That said, since the minidriver is emulating a card that should have a cardid file,
>>> the data to populate the emulated cardid file has to come from the card and be the same
>>> at every use,  and unique across all cards not just one site or one card vendor.
>>>
>>> The value or its derivatives are stored in the certificate store and used
>>> to associate cards with data previously cached.
>>>
>>>> I therefore propose to change the code in minidriver.c to do the following:
>>>>
>>>> 1. try parsing tokeninfo->serial_number as hex string
>>>> 2. if that fails copy serial_number as is with the length being the
>>>> length of the ASCII encoded string
>>> It must be 16 bytes.
>>>
>>>> This should not interfere with current card drivers which all use a hex
>>>> string as serial number.
>>>>
>>>> Any objections ?
>>> If you can show that your method has enough uniqueness, to not cause problems
>>> with other cards, then no.
>>>
>>>> Andreas
>>>>
>>


--

    ---------    CardContact Software & System Consulting
   |.##> <##.|   Andreas Schwier
   |#       #|   Schülerweg 38
   |#       #|   32429 Minden, Germany
   |'##> <##'|   Phone +49 171 8334920
    ---------    http://www.cardcontact.de
                 http://www.tscons.de
                 http://www.openscdp.org

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Minidriver assume hexstring encoding for card serial number

Douglas E. Engert


On 8/22/2012 11:24 AM, Andreas Schwier (ML) wrote:

> Hi Douglas,
>
> see below.
>
> Am 22.08.2012 18:00, schrieb Douglas E. Engert:
>>
>> On 8/22/2012 10:09 AM, Andreas Schwier wrote:
>>> Hi Douglas,
>>>
>>> thanks for your infos.
>>>
>>> The minidriver.c already ensures that the cardid file is always 16 byte.
>>> It does this by repeating the token serial number until 16 bytes are filled.
>> Unfortunately that gives OpenbSC 16 bytes but does not improve the uniqunness.
>>
>> Fortunately the uniqueness today only needs to extend over all the cards
>> as seen on a single machine which may be only a hand full. the cardid
>> is not sent to AD for example.  But it also means that if the certificates
>> or keys on a card are changed, the cardid should also change.
>>
>>> We can ensure uniqueness of the serial number for our cards, but no
>>> uniqueness among all other card vendors. There remains a (very) little
>>> probability that a hexadecimal encoded serial number of another vendor's
>>> card resembles one of our ASCII serial numbers.
>>>
>>> Our serial numbers are based on the numbering scheme for machine
>>> readable travel documents, a 2 digit country code followed by up to 9
>>> ASCII digits (e.g. UTTM1234567 equals 5554544D313233343536375554544D31
>>> in cardid).
>> You did not say what was the minimum number of digits are, and
>> in you example the first 4 "ACSII digits" are letters not numbers that
>> introduce more uniqueness then numbers. Also for a single machine would
>> it always see the same country code?
> The serial number is always 11 characters (0-9, A-Z). The country code
> is the country of the card issuer, within a country the card issuer gets
> a 2-character prefix and will define the remaining 7 character.

OK, so you are looking at how to handle the failure
in minidriver.c at line 1071,  not on getting a printable string to show up.

1069                 rv = sc_hex_to_bin(vs->p15card->tokeninfo->serial_number, sn_bin, &sn_len);
1070                 if (rv)
1071                         return SCARD_E_INVALID_VALUE;

  by change to something like:

        rv = sc_hex_to_bin(vs->p15card->tokeninfo->serial_number, sn_bin, &sn_len);
        if (rv) {
                strncpy(s_bin, vs->p15card->tokeninfo->serial_number, sizeof(sn_bin));
                sn_len = strlen(vs->p15card->tokeninfo->serial_number);
                if (sn_len < 2) /* really too short to use as a cardid */
                        return SCARD_E_INVALID_VALUE;
                if (sn_len > sizeof(sn_bin)) sn_len = sizeof(sn_bin);
        }

I have not tried this.

Since this fails, in your case, I don't have any objection to adding something
like the above.

>>
>> If you have 9 ASCII characters that should introduce enough uniqueness
>> to avoid conflicts with your other cards and other vendors cards.
>>
>> One point I am trying to make is the cardid value is not really seen
>> by the user, thus it does not have to be printable, and it could
>> hold more uniqueness then a printable string. But if there is not
>> enough unique data on the card to populate the cardid you have to use
>> whatever you have.
> Yes, I understand. I'm just concerned about the serial number visible to
> the user at the PKCS#15 and PKCS#11 level. There it would be nice to see
> the same serial number as the one printed on the card. My point is, that
> currently the minidriver silently assumes that the
> tokeninfo->serial_number contains a string with hexadecimal characters.
>>
>>> Our proposed change (see [1]) will not alter the current behaviour with
>>> existing cards. It will just allow a card that uses a ASCII serial
>>> number to work as well.
>>>
>>> An alternative approach - and probably more invasive - would be to use
>>> the result of SC_CARDCTL_GET_SERIALNR in minidriver.c as input for the
>>> cardid file. This way we could still have our human readable serial
>>> number at the PKCS#11 und PKCS#15 level and a little more uniqueness in
>>> the cardid file.
>> On some cards whewre there is no serial readable form the card the
>> SC_CARDCTL_GET_SERIALNR does similar tricts to come up with a "serial number"
>> from what ever data it can use on the card.
>>
>>
>>> This will however break existing installations, as the
>>> content of the cardid file might change with the driver update.
>>>
>> Yes it might break existing installations, as it would look like  a new card
>> to the application, but with the same certificate on two cards. This could be
>> an issue if Windows searches the cert store for a certificate, then asks the
>> user to insert the matching card. i.e. the old card, not the new one.
>>
>> As long as you have 6 digits or characters in your printable string that should
>> be fine.
>>
>>> Andreas
>>>
>>> [1]
>>> https://github.com/CardContact/OpenSC/commit/724cdd06e23ecd2e822bd1f138d9c3fbdafe9324
>>>
>>> Am 22.08.2012 16:29, schrieb Douglas E. Engert:
>>>> On 8/22/2012 5:28 AM, Andreas Schwier (ML) wrote:
>>>>> Hi everyone,
>>>>>
>>>>> we've come across an issue with the minidriver which assumes the card
>>>>> serial number to be a hex string.
>>>>>
>>>>> In our card the serial number is a string composed of ASCII characters.
>>>>> This works well with pkcs15-tool and the PKCS#11 library, however it
>>>>> fails with the current minidriver when it tries to convert the hex
>>>>> string into binary data for the cardid file.
>>>>>
>>>>> Neither in PKCS#11 spec nor in ISO 7816-15 I can find a definition for
>>>>> encoding the serial number as hex string.
>>>> The minidriver does not use the PKCS#11 standards, it is the Microsoft
>>>> definition of what it expects in the cardid file that counts.
>>>>
>>>> http://www.microsoft.com/whdc/device/input/smartcard/sc-minidriver.mspx
>>>>
>>>> Section 5.4.1 says:
>>>>
>>>>     "The logical name for this file is “CardId”. It is in the root directory."
>>>>
>>>>     "The file is organized as a 16-byte array. It should be treated as opaque binary data."
>>>>
>>>>     "This value is assigned by Microsoft software to assure that a unique value is
>>>>      generated for the card. It is unrelated to the serial number that may or may not
>>>>      be assigned to the card during manufacture."
>>>>
>>>> In other places it calls it as a GUID.
>>>>
>>>> This also means that when displayed, it maybe displayed as a GUID as hex digits
>>>> with "{", "}" "," and "-"  added for readability, and some bytes reversed in little
>>>> endian machines. So it may not be recognizable as your serial number.
>>>>
>>>> That said, since the minidriver is emulating a card that should have a cardid file,
>>>> the data to populate the emulated cardid file has to come from the card and be the same
>>>> at every use,  and unique across all cards not just one site or one card vendor.
>>>>
>>>> The value or its derivatives are stored in the certificate store and used
>>>> to associate cards with data previously cached.
>>>>
>>>>> I therefore propose to change the code in minidriver.c to do the following:
>>>>>
>>>>> 1. try parsing tokeninfo->serial_number as hex string
>>>>> 2. if that fails copy serial_number as is with the length being the
>>>>> length of the ASCII encoded string
>>>> It must be 16 bytes.
>>>>
>>>>> This should not interfere with current card drivers which all use a hex
>>>>> string as serial number.
>>>>>
>>>>> Any objections ?
>>>> If you can show that your method has enough uniqueness, to not cause problems
>>>> with other cards, then no.
>>>>
>>>>> Andreas
>>>>>
>>>
>
>

--

  Douglas E. Engert  <[hidden email]>
  Argonne National Laboratory
  9700 South Cass Avenue
  Argonne, Illinois  60439
  (630) 252-5444


_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Minidriver assume hexstring encoding for card serial number

Andreas Schwier
Yes, that's basically what our patch is all about. There are actually
two places in minidriver.c where the tokeninfo->serial_number value is
copied. We propose to change both as you can see in [1].

Andreas

[1]
https://github.com/CardContact/OpenSC/commit/724cdd06e23ecd2e822bd1f138d9c3fbdafe9324

Am 22.08.2012 20:30, schrieb Douglas E. Engert:

>
> On 8/22/2012 11:24 AM, Andreas Schwier (ML) wrote:
>> Hi Douglas,
>>
>> see below.
>>
>> Am 22.08.2012 18:00, schrieb Douglas E. Engert:
>>> On 8/22/2012 10:09 AM, Andreas Schwier wrote:
>>>> Hi Douglas,
>>>>
>>>> thanks for your infos.
>>>>
>>>> The minidriver.c already ensures that the cardid file is always 16 byte.
>>>> It does this by repeating the token serial number until 16 bytes are filled.
>>> Unfortunately that gives OpenbSC 16 bytes but does not improve the uniqunness.
>>>
>>> Fortunately the uniqueness today only needs to extend over all the cards
>>> as seen on a single machine which may be only a hand full. the cardid
>>> is not sent to AD for example.  But it also means that if the certificates
>>> or keys on a card are changed, the cardid should also change.
>>>
>>>> We can ensure uniqueness of the serial number for our cards, but no
>>>> uniqueness among all other card vendors. There remains a (very) little
>>>> probability that a hexadecimal encoded serial number of another vendor's
>>>> card resembles one of our ASCII serial numbers.
>>>>
>>>> Our serial numbers are based on the numbering scheme for machine
>>>> readable travel documents, a 2 digit country code followed by up to 9
>>>> ASCII digits (e.g. UTTM1234567 equals 5554544D313233343536375554544D31
>>>> in cardid).
>>> You did not say what was the minimum number of digits are, and
>>> in you example the first 4 "ACSII digits" are letters not numbers that
>>> introduce more uniqueness then numbers. Also for a single machine would
>>> it always see the same country code?
>> The serial number is always 11 characters (0-9, A-Z). The country code
>> is the country of the card issuer, within a country the card issuer gets
>> a 2-character prefix and will define the remaining 7 character.
> OK, so you are looking at how to handle the failure
> in minidriver.c at line 1071,  not on getting a printable string to show up.
>
> 1069                 rv = sc_hex_to_bin(vs->p15card->tokeninfo->serial_number, sn_bin, &sn_len);
> 1070                 if (rv)
> 1071                         return SCARD_E_INVALID_VALUE;
>
>   by change to something like:
>
> rv = sc_hex_to_bin(vs->p15card->tokeninfo->serial_number, sn_bin, &sn_len);
> if (rv) {
> strncpy(s_bin, vs->p15card->tokeninfo->serial_number, sizeof(sn_bin));
> sn_len = strlen(vs->p15card->tokeninfo->serial_number);
> if (sn_len < 2) /* really too short to use as a cardid */
> return SCARD_E_INVALID_VALUE;
> if (sn_len > sizeof(sn_bin)) sn_len = sizeof(sn_bin);
> }
>
> I have not tried this.
>
> Since this fails, in your case, I don't have any objection to adding something
> like the above.
>
>>> If you have 9 ASCII characters that should introduce enough uniqueness
>>> to avoid conflicts with your other cards and other vendors cards.
>>>
>>> One point I am trying to make is the cardid value is not really seen
>>> by the user, thus it does not have to be printable, and it could
>>> hold more uniqueness then a printable string. But if there is not
>>> enough unique data on the card to populate the cardid you have to use
>>> whatever you have.
>> Yes, I understand. I'm just concerned about the serial number visible to
>> the user at the PKCS#15 and PKCS#11 level. There it would be nice to see
>> the same serial number as the one printed on the card. My point is, that
>> currently the minidriver silently assumes that the
>> tokeninfo->serial_number contains a string with hexadecimal characters.
>>>> Our proposed change (see [1]) will not alter the current behaviour with
>>>> existing cards. It will just allow a card that uses a ASCII serial
>>>> number to work as well.
>>>>
>>>> An alternative approach - and probably more invasive - would be to use
>>>> the result of SC_CARDCTL_GET_SERIALNR in minidriver.c as input for the
>>>> cardid file. This way we could still have our human readable serial
>>>> number at the PKCS#11 und PKCS#15 level and a little more uniqueness in
>>>> the cardid file.
>>> On some cards whewre there is no serial readable form the card the
>>> SC_CARDCTL_GET_SERIALNR does similar tricts to come up with a "serial number"
>>> from what ever data it can use on the card.
>>>
>>>
>>>> This will however break existing installations, as the
>>>> content of the cardid file might change with the driver update.
>>>>
>>> Yes it might break existing installations, as it would look like  a new card
>>> to the application, but with the same certificate on two cards. This could be
>>> an issue if Windows searches the cert store for a certificate, then asks the
>>> user to insert the matching card. i.e. the old card, not the new one.
>>>
>>> As long as you have 6 digits or characters in your printable string that should
>>> be fine.
>>>
>>>> Andreas
>>>>
>>>> [1]
>>>> https://github.com/CardContact/OpenSC/commit/724cdd06e23ecd2e822bd1f138d9c3fbdafe9324
>>>>
>>>> Am 22.08.2012 16:29, schrieb Douglas E. Engert:
>>>>> On 8/22/2012 5:28 AM, Andreas Schwier (ML) wrote:
>>>>>> Hi everyone,
>>>>>>
>>>>>> we've come across an issue with the minidriver which assumes the card
>>>>>> serial number to be a hex string.
>>>>>>
>>>>>> In our card the serial number is a string composed of ASCII characters.
>>>>>> This works well with pkcs15-tool and the PKCS#11 library, however it
>>>>>> fails with the current minidriver when it tries to convert the hex
>>>>>> string into binary data for the cardid file.
>>>>>>
>>>>>> Neither in PKCS#11 spec nor in ISO 7816-15 I can find a definition for
>>>>>> encoding the serial number as hex string.
>>>>> The minidriver does not use the PKCS#11 standards, it is the Microsoft
>>>>> definition of what it expects in the cardid file that counts.
>>>>>
>>>>> http://www.microsoft.com/whdc/device/input/smartcard/sc-minidriver.mspx
>>>>>
>>>>> Section 5.4.1 says:
>>>>>
>>>>>     "The logical name for this file is “CardId”. It is in the root directory."
>>>>>
>>>>>     "The file is organized as a 16-byte array. It should be treated as opaque binary data."
>>>>>
>>>>>     "This value is assigned by Microsoft software to assure that a unique value is
>>>>>      generated for the card. It is unrelated to the serial number that may or may not
>>>>>      be assigned to the card during manufacture."
>>>>>
>>>>> In other places it calls it as a GUID.
>>>>>
>>>>> This also means that when displayed, it maybe displayed as a GUID as hex digits
>>>>> with "{", "}" "," and "-"  added for readability, and some bytes reversed in little
>>>>> endian machines. So it may not be recognizable as your serial number.
>>>>>
>>>>> That said, since the minidriver is emulating a card that should have a cardid file,
>>>>> the data to populate the emulated cardid file has to come from the card and be the same
>>>>> at every use,  and unique across all cards not just one site or one card vendor.
>>>>>
>>>>> The value or its derivatives are stored in the certificate store and used
>>>>> to associate cards with data previously cached.
>>>>>
>>>>>> I therefore propose to change the code in minidriver.c to do the following:
>>>>>>
>>>>>> 1. try parsing tokeninfo->serial_number as hex string
>>>>>> 2. if that fails copy serial_number as is with the length being the
>>>>>> length of the ASCII encoded string
>>>>> It must be 16 bytes.
>>>>>
>>>>>> This should not interfere with current card drivers which all use a hex
>>>>>> string as serial number.
>>>>>>
>>>>>> Any objections ?
>>>>> If you can show that your method has enough uniqueness, to not cause problems
>>>>> with other cards, then no.
>>>>>
>>>>>> Andreas
>>>>>>
>>


--

    ---------    CardContact Software & System Consulting
   |.##> <##.|   Andreas Schwier
   |#       #|   Schülerweg 38
   |#       #|   32429 Minden, Germany
   |'##> <##'|   Phone +49 171 8334920
    ---------    http://www.cardcontact.de
                 http://www.tscons.de
                 http://www.openscdp.org

_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel
Reply | Threaded
Open this post in threaded view
|

Re: Minidriver assume hexstring encoding for card serial number

Douglas E. Engert


On 8/22/2012 1:53 PM, Andreas Schwier wrote:
> Yes, that's basically what our patch is all about. There are actually
> two places in minidriver.c where the tokeninfo->serial_number value is
> copied. We propose to change both as you can see in [1].

Looks good.

>
> Andreas
>
> [1]
> https://github.com/CardContact/OpenSC/commit/724cdd06e23ecd2e822bd1f138d9c3fbdafe9324
>
> Am 22.08.2012 20:30, schrieb Douglas E. Engert:
>>
>> On 8/22/2012 11:24 AM, Andreas Schwier (ML) wrote:
>>> Hi Douglas,
>>>
>>> see below.
>>>
>>> Am 22.08.2012 18:00, schrieb Douglas E. Engert:
>>>> On 8/22/2012 10:09 AM, Andreas Schwier wrote:
>>>>> Hi Douglas,
>>>>>
>>>>> thanks for your infos.
>>>>>
>>>>> The minidriver.c already ensures that the cardid file is always 16 byte.
>>>>> It does this by repeating the token serial number until 16 bytes are filled.
>>>> Unfortunately that gives OpenbSC 16 bytes but does not improve the uniqunness.
>>>>
>>>> Fortunately the uniqueness today only needs to extend over all the cards
>>>> as seen on a single machine which may be only a hand full. the cardid
>>>> is not sent to AD for example.  But it also means that if the certificates
>>>> or keys on a card are changed, the cardid should also change.
>>>>
>>>>> We can ensure uniqueness of the serial number for our cards, but no
>>>>> uniqueness among all other card vendors. There remains a (very) little
>>>>> probability that a hexadecimal encoded serial number of another vendor's
>>>>> card resembles one of our ASCII serial numbers.
>>>>>
>>>>> Our serial numbers are based on the numbering scheme for machine
>>>>> readable travel documents, a 2 digit country code followed by up to 9
>>>>> ASCII digits (e.g. UTTM1234567 equals 5554544D313233343536375554544D31
>>>>> in cardid).
>>>> You did not say what was the minimum number of digits are, and
>>>> in you example the first 4 "ACSII digits" are letters not numbers that
>>>> introduce more uniqueness then numbers. Also for a single machine would
>>>> it always see the same country code?
>>> The serial number is always 11 characters (0-9, A-Z). The country code
>>> is the country of the card issuer, within a country the card issuer gets
>>> a 2-character prefix and will define the remaining 7 character.
>> OK, so you are looking at how to handle the failure
>> in minidriver.c at line 1071,  not on getting a printable string to show up.
>>
>> 1069                 rv = sc_hex_to_bin(vs->p15card->tokeninfo->serial_number, sn_bin, &sn_len);
>> 1070                 if (rv)
>> 1071                         return SCARD_E_INVALID_VALUE;
>>
>>    by change to something like:
>>
>> rv = sc_hex_to_bin(vs->p15card->tokeninfo->serial_number, sn_bin, &sn_len);
>> if (rv) {
>> strncpy(s_bin, vs->p15card->tokeninfo->serial_number, sizeof(sn_bin));
>> sn_len = strlen(vs->p15card->tokeninfo->serial_number);
>> if (sn_len < 2) /* really too short to use as a cardid */
>> return SCARD_E_INVALID_VALUE;
>> if (sn_len > sizeof(sn_bin)) sn_len = sizeof(sn_bin);
>> }
>>
>> I have not tried this.
>>
>> Since this fails, in your case, I don't have any objection to adding something
>> like the above.
>>
>>>> If you have 9 ASCII characters that should introduce enough uniqueness
>>>> to avoid conflicts with your other cards and other vendors cards.
>>>>
>>>> One point I am trying to make is the cardid value is not really seen
>>>> by the user, thus it does not have to be printable, and it could
>>>> hold more uniqueness then a printable string. But if there is not
>>>> enough unique data on the card to populate the cardid you have to use
>>>> whatever you have.
>>> Yes, I understand. I'm just concerned about the serial number visible to
>>> the user at the PKCS#15 and PKCS#11 level. There it would be nice to see
>>> the same serial number as the one printed on the card. My point is, that
>>> currently the minidriver silently assumes that the
>>> tokeninfo->serial_number contains a string with hexadecimal characters.
>>>>> Our proposed change (see [1]) will not alter the current behaviour with
>>>>> existing cards. It will just allow a card that uses a ASCII serial
>>>>> number to work as well.
>>>>>
>>>>> An alternative approach - and probably more invasive - would be to use
>>>>> the result of SC_CARDCTL_GET_SERIALNR in minidriver.c as input for the
>>>>> cardid file. This way we could still have our human readable serial
>>>>> number at the PKCS#11 und PKCS#15 level and a little more uniqueness in
>>>>> the cardid file.
>>>> On some cards whewre there is no serial readable form the card the
>>>> SC_CARDCTL_GET_SERIALNR does similar tricts to come up with a "serial number"
>>>> from what ever data it can use on the card.
>>>>
>>>>
>>>>> This will however break existing installations, as the
>>>>> content of the cardid file might change with the driver update.
>>>>>
>>>> Yes it might break existing installations, as it would look like  a new card
>>>> to the application, but with the same certificate on two cards. This could be
>>>> an issue if Windows searches the cert store for a certificate, then asks the
>>>> user to insert the matching card. i.e. the old card, not the new one.
>>>>
>>>> As long as you have 6 digits or characters in your printable string that should
>>>> be fine.
>>>>
>>>>> Andreas
>>>>>
>>>>> [1]
>>>>> https://github.com/CardContact/OpenSC/commit/724cdd06e23ecd2e822bd1f138d9c3fbdafe9324
>>>>>
>>>>> Am 22.08.2012 16:29, schrieb Douglas E. Engert:
>>>>>> On 8/22/2012 5:28 AM, Andreas Schwier (ML) wrote:
>>>>>>> Hi everyone,
>>>>>>>
>>>>>>> we've come across an issue with the minidriver which assumes the card
>>>>>>> serial number to be a hex string.
>>>>>>>
>>>>>>> In our card the serial number is a string composed of ASCII characters.
>>>>>>> This works well with pkcs15-tool and the PKCS#11 library, however it
>>>>>>> fails with the current minidriver when it tries to convert the hex
>>>>>>> string into binary data for the cardid file.
>>>>>>>
>>>>>>> Neither in PKCS#11 spec nor in ISO 7816-15 I can find a definition for
>>>>>>> encoding the serial number as hex string.
>>>>>> The minidriver does not use the PKCS#11 standards, it is the Microsoft
>>>>>> definition of what it expects in the cardid file that counts.
>>>>>>
>>>>>> http://www.microsoft.com/whdc/device/input/smartcard/sc-minidriver.mspx
>>>>>>
>>>>>> Section 5.4.1 says:
>>>>>>
>>>>>>      "The logical name for this file is “CardId”. It is in the root directory."
>>>>>>
>>>>>>      "The file is organized as a 16-byte array. It should be treated as opaque binary data."
>>>>>>
>>>>>>      "This value is assigned by Microsoft software to assure that a unique value is
>>>>>>       generated for the card. It is unrelated to the serial number that may or may not
>>>>>>       be assigned to the card during manufacture."
>>>>>>
>>>>>> In other places it calls it as a GUID.
>>>>>>
>>>>>> This also means that when displayed, it maybe displayed as a GUID as hex digits
>>>>>> with "{", "}" "," and "-"  added for readability, and some bytes reversed in little
>>>>>> endian machines. So it may not be recognizable as your serial number.
>>>>>>
>>>>>> That said, since the minidriver is emulating a card that should have a cardid file,
>>>>>> the data to populate the emulated cardid file has to come from the card and be the same
>>>>>> at every use,  and unique across all cards not just one site or one card vendor.
>>>>>>
>>>>>> The value or its derivatives are stored in the certificate store and used
>>>>>> to associate cards with data previously cached.
>>>>>>
>>>>>>> I therefore propose to change the code in minidriver.c to do the following:
>>>>>>>
>>>>>>> 1. try parsing tokeninfo->serial_number as hex string
>>>>>>> 2. if that fails copy serial_number as is with the length being the
>>>>>>> length of the ASCII encoded string
>>>>>> It must be 16 bytes.
>>>>>>
>>>>>>> This should not interfere with current card drivers which all use a hex
>>>>>>> string as serial number.
>>>>>>>
>>>>>>> Any objections ?
>>>>>> If you can show that your method has enough uniqueness, to not cause problems
>>>>>> with other cards, then no.
>>>>>>
>>>>>>> Andreas
>>>>>>>
>>>
>
>

--

  Douglas E. Engert  <[hidden email]>
  Argonne National Laboratory
  9700 South Cass Avenue
  Argonne, Illinois  60439
  (630) 252-5444


_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc-project.org/mailman/listinfo/opensc-devel