Giter Club home page Giter Club logo

Comments (25)

dengert avatar dengert commented on July 18, 2024 2

Here is problem:

In https://gist.github.com/RufusJWB/b1b2183421eb9df81686237262f65f68 running 0.23.0 on Windows 11:

lines starting at 8210:

Incoming APDU (257 bytes):
02 7A 30 0D CC C3 99 3D AD 0A C5 8F 9C 45 07 6C .z0....=.....E.l
53 32 F3 44 0B 62 D3 29 2F 5C 64 A1 6D 05 93 D0 S2.D.b.)/\d.m...
5F 11 2F 41 E4 45 22 B3 71 C2 79 B5 0C 4E 0D 5A _./A.E".q.y..N.Z
44 24 43 EE AF 7C 0B 1F 33 43 1A 31 FC EE 58 6E D$C..|..3C.1..Xn
99 31 75 BD E2 B9 99 A2 13 44 22 BA 44 27 3B 93 .1u......D".D';.
33 A4 7F 4E B8 8C B9 9E 67 94 21 9C F5 AC 72 A9 3..N....g.!...r.
E1 9B B9 DD E4 EE 16 22 C2 83 EE 04 9A 4A 71 81 .......".....Jq.
86 59 8C A4 16 C9 2A BD 50 29 1D EC D1 E2 39 41 .Y....*.P)....9A
BE F8 2B 4B F0 92 EB D2 4D 57 BA 70 A7 A2 82 D7 ..+K....MW.p....
E3 AB 83 8D 76 A3 14 C0 34 52 A0 B9 C0 8A BD 9B ....v...4R......
E9 B8 98 55 A0 21 FC 8A 7F 11 99 97 C3 86 18 FD ...U.!..........
B5 BB 6D 26 F8 25 3B E1 7F 90 D0 F9 C1 1F CA A6 ..m&.%;.........
3D 03 73 50 A4 E0 1D B0 21 D4 7D 3F 95 79 AF CA =.sP....!.}?.y..
C2 7E E9 0C 10 67 BC 46 EB 42 FA 90 C8 22 D5 5D .~...g.F.B...".]
60 C9 F2 C7 9B 6F 56 9E 0D DD FF 0A 26 9F 00 CE `....oV.....&...
EA 18 22 C6 8C 24 DD 45 6C E3 25 25 18 27 43 90 .."..$.El.%%.'C.
00 

257 bytes -2 bytes status = 255 data bytes. This should be PKCS1.5 padded that should start with 00 02
But leading 0x00 byte is missing. Looks like device is doing SC_ALGORITHM_RSA_RAW.

When called from minidriver card-cardos.c:cardos_decipher should catch this and add leading 0x00 back in but did not.
.

P:12372; T:12384 2023-11-15 17:43:35.834 [cardmod] apdu.c:382:sc_single_transmit: returning with: 0 (Success)
P:12372; T:12384 2023-11-15 17:43:35.834 [cardmod] apdu.c:539:sc_transmit: returning with: 0 (Success)
P:12372; T:12384 2023-11-15 17:43:35.834 [cardmod] card.c:530:sc_unlock: called
P:12372; T:12384 2023-11-15 17:43:35.834 [cardmod] iso7816.c:1057:iso7816_decipher: returning with: 255
P:12372; T:12384 2023-11-15 17:43:35.834 [cardmod] card-cardos.c:1239:cardos_decipher: returning with: 255
P:12372; T:12384 2023-11-15 17:43:35.840 [cardmod] sec.c:50:sc_decipher: returning with: 255
P:12372; T:12384 2023-11-15 17:43:35.840 [cardmod] card.c:530:sc_unlock: called
P:12372; T:12384 2023-11-15 17:43:35.840 [cardmod] pkcs15-sec.c:169:use_key: returning with: 255
P:12372; T:12384 2023-11-15 17:43:35.840 [cardmod] pkcs15-sec.c:335:sc_pkcs15_decipher: returning with: 255

The next 3 are from minidriver:

P:12372; T:12384 2023-11-15 17:43:35.840 [cardmod] sc_pkcs15_decipher returned 255
P:12372; T:12384 2023-11-15 17:43:35.840 [cardmod] sc_pkcs15_decipher: DECRYPT-INFO dwVersion=2
P:12372; T:12384 2023-11-15 17:43:35.840 [cardmod] sc_pkcs15_decipher: stripping PKCS1 padding
P:12372; T:12384 2023-11-15 17:43:35.840 [cardmod] padding.c:154:sc_pkcs1_strip_02_padding: called

Looks like padding sc_pkcs1_strip_02_padding does not handle missing leading zero, so ends up returning 17 bytes

EA 18 22 C6 8C 24 DD 45 6C E3 25 25 18 27 43 00

but should have returned 16 bytes with out the trailing 00

P:12372; T:12384 2023-11-15 17:43:35.840 [cardmod] stripped output(17): CEEA1822C68C24DD456CE32525182743 00
P:12372; T:12384 2023-11-15 17:43:35.840 [cardmod] padding.c:184:sc_pkcs1_strip_02_padding: returning with: 17
P:12372; T:12384 2023-11-15 17:43:35.840 [cardmod] decrypted data(17):

Simplest solution is:

diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c
index 980e82ac8..3391994ab 100644
--- a/src/minidriver/minidriver.c
+++ b/src/minidriver/minidriver.c
@@ -4643,7 +4643,7 @@ DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData,
 
        if (alg_info->flags & SC_ALGORITHM_RSA_RAW)   {
                logprintf(pCardData, 2, "sc_pkcs15_decipher: using RSA-RAW mechanism\n");
-               r = sc_pkcs15_decipher(vs->p15card, pkey, opt_crypt_flags, pbuf, pInfo->cbData, pbuf2, pInfo->cbData, NULL);
+               r = sc_pkcs15_decipher(vs->p15card, pkey, opt_crypt_flags | SC_ALGORITHM_RSA_RAW, pbuf, pInfo->cbData, pbuf2, pInfo->cbData, NULL);
                logprintf(pCardData, 2, "sc_pkcs15_decipher returned %d\n", r);
 
                if (r > 0) {

from opensc.

dengert avatar dengert commented on July 18, 2024 1

RSA raw decryption should return 256 bytes. There is a 1 in 256 chance the first byte may be 0x00. The above logs look like they return 255 bytes and the 2 status bytes.
Could their card strips leading zeros in response and their driver handles this but OpenSC does not?
The modulus and results are treated as big numbers.

If the modulus for this key has a few leading zero bit too, which limits the size of the input data to the modulus and thus the size of the decrypted data to, change the probability of leading zero bits . What is modules for this key?

from opensc.

dengert avatar dengert commented on July 18, 2024 1

Here is one other possible issue. The Altos driver maybe creating container numbers that are different from the container numbers created by OpenSC for the same card.

So you may have to

Windows like to cache certificates based on these number. So if you switch drivers back and forth windows may get confused.

Can you run certutil -v -scinfo using the OpenSC driver?

from opensc.

dengert avatar dengert commented on July 18, 2024 1

@RufusJWB PR #2939 should fix the problem. But it needs to be tested by you. Windows install files are built with this PR based on master and can be found by going to #2939

Near the bottom look for "Some checks havenโ€™t completed yet" or "All checks have passed"
Click on "Show all checks" if needed
Scroll down to "continuous-integration/appveyor/pr"
Click on "Details"
You will find 8 jobs.
The 5th and 6th jobs will be for Platform x86 and Platform x64
When you click on these, you can click on "Artifacts" to see the the Windows "msi" files. for the win32 and win64

Based on last built these would be:
https://ci.appveyor.com/api/buildjobs/dlvvwbqsexif9vda/artifacts/OpenSC-0.24.0-rc1_win32.msi
https://ci.appveyor.com/api/buildjobs/o8am4x1pir5vl2ec/artifacts/OpenSC-0.24.0-rc1_win64.msi

from opensc.

RufusJWB avatar RufusJWB commented on July 18, 2024 1

I can confirm it works. Thank you very much for your support and your patience!

from opensc.

RufusJWB avatar RufusJWB commented on July 18, 2024

If needed, I could provide you with an CardOS 5.3 card

from opensc.

Jakuje avatar Jakuje commented on July 18, 2024

I assume this is some log from the minidriver (?). I am not familiar with that format much.

I see CardRSADecrypt being called at two places and both look like returning success (I think: returning with: 0x00000000). So it looks like the deciphering was ok, but the outlook did not like the returned value? Do you have for a reference same log for the atos card driver?

Do you have debug logs from the OpenSC when it failed to decrypt the mails. I think this would be helpful.

from opensc.

RufusJWB avatar RufusJWB commented on July 18, 2024

The mini driver debug logs are generated by OpenSC:

Write minidriver debug information to

Please find in this gist the full logs. I only removed the pin value: https://gist.github.com/RufusJWB/908b30f39af41964d0863063bbc665be

from opensc.

Jakuje avatar Jakuje commented on July 18, 2024

I see 4 attempts to decrypt the same block of data using the same APDU, all successful on the opens layer, returning 17 bytes of data. I do not see any failure in the logs. Can the outlook provide some disgnostic information about the failure?

One way to check what the atos driver is doing is to record the APDUs it does on the pcsc layer and compare it with the APDU from the above log, but I am not sure how to do that on Windows. It can show some hack/fallback their driver does with some corner-case issue. But its always hard to figure out without specification.

from opensc.

frankmorgner avatar frankmorgner commented on July 18, 2024

You may want to use this tool with the Atos driver: https://www.mysmartlogon.com/knowledge-base/trace-apdu-on-windows/

from opensc.

RufusJWB avatar RufusJWB commented on July 18, 2024

You may want to use this tool with the Atos driver: https://www.mysmartlogon.com/knowledge-base/trace-apdu-on-windows/

This tool didn't work for me under Windows 11 but I was able to find out the necessary registry keys so that AtoS mini driver is creating the logs:

Minidriver logging triggered by Outlook process
Scard logging triggered by Outlook process
Certstore logging triggered by System process

from opensc.

Jakuje avatar Jakuje commented on July 18, 2024

Looking at the low leve decryption APDU logs, the logs look almost the same (the important parts inputs and outputs are completely same) for both atos driver and opensc. This is from OpenSC from #2925 (comment):

### select file
Outgoing APDU (11 bytes):
00 A4 08 0C 06 50 15 50 72 4B 02 .....P.PrK.

P:11916; T:34500 2023-11-03 18:36:24.891 [cardmod] reader-pcsc.c:244:pcsc_internal_transmit: called
P:11916; T:34500 2023-11-03 18:36:24.939 [cardmod] reader-pcsc.c:335:pcsc_transmit: 
Incoming APDU (2 bytes):
90 00 ..

[...]
### set security env
Outgoing APDU (11 bytes):
00 22 41 B8 06 84 01 02 95 01 40 ."A.......@

P:11916; T:34500 2023-11-03 18:36:24.939 [cardmod] reader-pcsc.c:244:pcsc_internal_transmit: called
P:11916; T:34500 2023-11-03 18:36:24.971 [cardmod] reader-pcsc.c:335:pcsc_transmit: 
Incoming APDU (2 bytes):
90 00 ..

[...]
# pefrorm security operation
00 2A 80 86 00 01 01 00 71 0B 02 88 F8 0B 7F B5 .*......q.......
E4 ED D6 87 F7 88 32 8F A6 92 7B 45 16 AB E3 9F ......2...{E....
05 B4 11 20 2E 57 1E 2E 7C 14 1B CD ED DE 3C DA ... .W..|.....<.
A6 E8 36 50 79 A2 83 F9 09 D4 4D 63 31 FB 91 8F ..6Py.....Mc1...
F4 95 3D 79 EE 8D D5 64 76 5A C4 F3 19 19 AD DA ..=y...dvZ......
A8 E7 D3 C4 0E 8F 63 F5 82 7B 63 69 CE 9C 23 F4 ......c..{ci..#.
91 47 B0 7E FC EB A8 A1 AA B3 8D 63 5B AD EC 41 .G.~.......c[..A
B5 65 C6 39 76 62 CE 34 03 7E 86 05 5D AD C3 33 .e.9vb.4.~..]..3
93 8D 4D 6E 0B D4 77 15 3A 31 E0 06 D5 D0 64 27 ..Mn..w.:1....d'
C2 61 F3 04 83 64 FB 6A 7E AF 1A 85 1C 94 D3 3B .a...d.j~......;
24 3E DB DA 21 1B 13 19 C1 57 44 78 B4 89 73 F0 $>..!....WDx..s.
0E 1F D6 E3 1C C8 DD C5 7F 7F EA 8B FE 90 96 51 ...............Q
49 F7 DC 74 88 D3 6E 58 C9 44 6F 4D 89 E1 42 6E I..t..nX.DoM..Bn
B5 34 13 CA DC C6 47 C8 1B 0E 86 2E 83 1D 33 93 .4....G.......3.
AB AE 2D 58 F8 04 AB A5 67 01 C5 81 3E 87 A2 C8 ..-X....g...>...
35 04 EA E1 D4 86 4F 59 CE 3D CC B7 93 EF 62 57 5.....OY.=....bW
9A ED 1D 1A 5E 9C 52 E7 01 00                   ....^.R...

P:11916; T:34500 2023-11-03 18:36:24.987 [cardmod] reader-pcsc.c:244:pcsc_internal_transmit: called
P:11916; T:34500 2023-11-03 18:36:25.386 [cardmod] reader-pcsc.c:335:pcsc_transmit: 
Incoming APDU (257 bytes):
02 7A 30 0D CC C3 99 3D AD 0A C5 8F 9C 45 07 6C .z0....=.....E.l
53 32 F3 44 0B 62 D3 29 2F 5C 64 A1 6D 05 93 D0 S2.D.b.)/\d.m...
5F 11 2F 41 E4 45 22 B3 71 C2 79 B5 0C 4E 0D 5A _./A.E".q.y..N.Z
44 24 43 EE AF 7C 0B 1F 33 43 1A 31 FC EE 58 6E D$C..|..3C.1..Xn
99 31 75 BD E2 B9 99 A2 13 44 22 BA 44 27 3B 93 .1u......D".D';.
33 A4 7F 4E B8 8C B9 9E 67 94 21 9C F5 AC 72 A9 3..N....g.!...r.
E1 9B B9 DD E4 EE 16 22 C2 83 EE 04 9A 4A 71 81 .......".....Jq.
86 59 8C A4 16 C9 2A BD 50 29 1D EC D1 E2 39 41 .Y....*.P)....9A
BE F8 2B 4B F0 92 EB D2 4D 57 BA 70 A7 A2 82 D7 ..+K....MW.p....
E3 AB 83 8D 76 A3 14 C0 34 52 A0 B9 C0 8A BD 9B ....v...4R......
E9 B8 98 55 A0 21 FC 8A 7F 11 99 97 C3 86 18 FD ...U.!..........
B5 BB 6D 26 F8 25 3B E1 7F 90 D0 F9 C1 1F CA A6 ..m&.%;.........
3D 03 73 50 A4 E0 1D B0 21 D4 7D 3F 95 79 AF CA =.sP....!.}?.y..
C2 7E E9 0C 10 67 BC 46 EB 42 FA 90 C8 22 D5 5D .~...g.F.B...".]
60 C9 F2 C7 9B 6F 56 9E 0D DD FF 0A 26 9F 00 CE `....oV.....&...
EA 18 22 C6 8C 24 DD 45 6C E3 25 25 18 27 43 90 .."..$.El.%%.'C.
00                                              .

Which has the same as data from scard logging from #2925 (comment) (I think even with the same values)

        ;-----------------------------------------------------------------------------
        ; 17516:17552 10:26:33.920 CardRSADecrypt()
        ;-----------------------------------------------------------------------------
        
;DEBUG: SCardBeginTransaction(hCard = 0xEA00000200000000) - waiting...
;DEBUG: SCardTransmit(hCard = 0xEA00000200000000)
;DEBUG: Wed Nov  8 10:26:33 2023
        
        [transmit]  ; SELECT FILE
        cla  =  000h
        ins  =  0A4h
        p1   =  008h
        p2   =  00Ch
        ;lc  =  006h
        data =  
              050h 015h 050h 072h 04Bh 002h 
        
;DEBUG: 0.021000s
;DEBUG: 
;DEBUG: SCardTransmit(hCard = 0xEA00000200000000)
;DEBUG: Wed Nov  8 10:26:33 2023
        
        [transmit]  ; GET CHALLENGE
        cla  =  000h
        ins  =  084h
        p1   =  000h
        p2   =  000h
        le   =  008h
        
        
        ;Response (8 bytes)
        resp =  
              025h 044h 0FAh 0E8h 015h 0BBh 09Eh 01Eh 
        sw1  =  090h
        sw2  =  000h
        
;DEBUG: 0.030000s
;DEBUG: 
; WARN: Using 2-key DES3 key.
;DEBUG: SCardTransmit(hCard = 0xEA00000200000000)
;DEBUG: Wed Nov  8 10:26:33 2023
        
        [transmit]  ; VERIFY
        cla  =  000h
        ins  =  020h
        p1   =  000h
        p2   =  091h
        ;lc  =  001h
        data =  
              [1 data bytes]
        
;DEBUG: 0.060000s
;DEBUG: 
;DEBUG: SCardTransmit(hCard = 0xEA00000200000000)
;DEBUG: Wed Nov  8 10:26:34 2023
        
        [transmit]  ; EXTERNAL AUTHENTICATE
        cla  =  000h
        ins  =  082h
        p1   =  000h
        p2   =  091h
        ;lc  =  008h
        data =  
              00Ch 072h 0EAh 08Fh 0BAh 00Fh 065h 096h 
        
;DEBUG: 0.045000s
;DEBUG: 
;DEBUG: SCardTransmit(hCard = 0xEA00000200000000)
;DEBUG: Wed Nov  8 10:26:34 2023
        
        [transmit]  ; MANAGE SECURITY ENVIRONMENT
        cla  =  000h
        ins  =  022h
        p1   =  0F3h
        p2   =  001h
        
;DEBUG: 0.030000s
;DEBUG: 
;DEBUG: SCardTransmit(hCard = 0xEA00000200000000)
;DEBUG: Wed Nov  8 10:26:34 2023
        
        [transmit]  ; MANAGE SECURITY ENVIRONMENT
        cla  =  000h
        ins  =  022h
        p1   =  041h
        p2   =  0B8h
        ;lc  =  006h
        data =  
              084h 001h 002h 095h 001h 040h 
        
;DEBUG: 0.030000s
;DEBUG: 
;DEBUG: SCardTransmit(hCard = 0xEA00000200000000)
;DEBUG: Wed Nov  8 10:26:34 2023
        
        [transmit]  ; PERFORM SECURITY OPERATION
        cla  =  000h
        ins  =  02Ah
        p1   =  080h
        p2   =  086h
        ;lc  =  101h
        data =  
              000h 071h 00Bh 002h 088h 0F8h 00Bh 07Fh 0B5h 0E4h 0EDh 0D6h 087h 0F7h 088h 032h 
              08Fh 0A6h 092h 07Bh 045h 016h 0ABh 0E3h 09Fh 005h 0B4h 011h 020h 02Eh 057h 01Eh 
              02Eh 07Ch 014h 01Bh 0CDh 0EDh 0DEh 03Ch 0DAh 0A6h 0E8h 036h 050h 079h 0A2h 083h 
              0F9h 009h 0D4h 04Dh 063h 031h 0FBh 091h 08Fh 0F4h 095h 03Dh 079h 0EEh 08Dh 0D5h 
              064h 076h 05Ah 0C4h 0F3h 019h 019h 0ADh 0DAh 0A8h 0E7h 0D3h 0C4h 00Eh 08Fh 063h 
              0F5h 082h 07Bh 063h 069h 0CEh 09Ch 023h 0F4h 091h 047h 0B0h 07Eh 0FCh 0EBh 0A8h 
              0A1h 0AAh 0B3h 08Dh 063h 05Bh 0ADh 0ECh 041h 0B5h 065h 0C6h 039h 076h 062h 0CEh 
              034h 003h 07Eh 086h 005h 05Dh 0ADh 0C3h 033h 093h 08Dh 04Dh 06Eh 00Bh 0D4h 077h 
              015h 03Ah 031h 0E0h 006h 0D5h 0D0h 064h 027h 0C2h 061h 0F3h 004h 083h 064h 0FBh 
              06Ah 07Eh 0AFh 01Ah 085h 01Ch 094h 0D3h 03Bh 024h 03Eh 0DBh 0DAh 021h 01Bh 013h 
              019h 0C1h 057h 044h 078h 0B4h 089h 073h 0F0h 00Eh 01Fh 0D6h 0E3h 01Ch 0C8h 0DDh 
              0C5h 07Fh 07Fh 0EAh 08Bh 0FEh 090h 096h 051h 049h 0F7h 0DCh 074h 088h 0D3h 06Eh 
              058h 0C9h 044h 06Fh 04Dh 089h 0E1h 042h 06Eh 0B5h 034h 013h 0CAh 0DCh 0C6h 047h 
              0C8h 01Bh 00Eh 086h 02Eh 083h 01Dh 033h 093h 0ABh 0AEh 02Dh 058h 0F8h 004h 0ABh 
              0A5h 067h 001h 0C5h 081h 03Eh 087h 0A2h 0C8h 035h 004h 0EAh 0E1h 0D4h 086h 04Fh 
              059h 0CEh 03Dh 0CCh 0B7h 093h 0EFh 062h 057h 09Ah 0EDh 01Dh 01Ah 05Eh 09Ch 052h 
              0E7h 
        le   =  001h 000h
        
        
        ;Response (255 bytes)
        resp =  
              002h 07Ah 030h 00Dh 0CCh 0C3h 099h 03Dh 0ADh 00Ah 0C5h 08Fh 09Ch 045h 007h 06Ch 
              053h 032h 0F3h 044h 00Bh 062h 0D3h 029h 02Fh 05Ch 064h 0A1h 06Dh 005h 093h 0D0h 
              05Fh 011h 02Fh 041h 0E4h 045h 022h 0B3h 071h 0C2h 079h 0B5h 00Ch 04Eh 00Dh 05Ah 
              044h 024h 043h 0EEh 0AFh 07Ch 00Bh 01Fh 033h 043h 01Ah 031h 0FCh 0EEh 058h 06Eh 
              099h 031h 075h 0BDh 0E2h 0B9h 099h 0A2h 013h 044h 022h 0BAh 044h 027h 03Bh 093h 
              033h 0A4h 07Fh 04Eh 0B8h 08Ch 0B9h 09Eh 067h 094h 021h 09Ch 0F5h 0ACh 072h 0A9h 
              0E1h 09Bh 0B9h 0DDh 0E4h 0EEh 016h 022h 0C2h 083h 0EEh 004h 09Ah 04Ah 071h 081h 
              086h 059h 08Ch 0A4h 016h 0C9h 02Ah 0BDh 050h 029h 01Dh 0ECh 0D1h 0E2h 039h 041h 
              0BEh 0F8h 02Bh 04Bh 0F0h 092h 0EBh 0D2h 04Dh 057h 0BAh 070h 0A7h 0A2h 082h 0D7h 
              0E3h 0ABh 083h 08Dh 076h 0A3h 014h 0C0h 034h 052h 0A0h 0B9h 0C0h 08Ah 0BDh 09Bh 
              0E9h 0B8h 098h 055h 0A0h 021h 0FCh 08Ah 07Fh 011h 099h 097h 0C3h 086h 018h 0FDh 
              0B5h 0BBh 06Dh 026h 0F8h 025h 03Bh 0E1h 07Fh 090h 0D0h 0F9h 0C1h 01Fh 0CAh 0A6h 
              03Dh 003h 073h 050h 0A4h 0E0h 01Dh 0B0h 021h 0D4h 07Dh 03Fh 095h 079h 0AFh 0CAh 
              0C2h 07Eh 0E9h 00Ch 010h 067h 0BCh 046h 0EBh 042h 0FAh 090h 0C8h 022h 0D5h 05Dh 
              060h 0C9h 0F2h 0C7h 09Bh 06Fh 056h 09Eh 00Dh 0DDh 0FFh 00Ah 026h 09Fh 000h 0CEh 
              0EAh 018h 022h 0C6h 08Ch 024h 0DDh 045h 06Ch 0E3h 025h 025h 018h 027h 043h 
        sw1  =  090h
        sw2  =  000h

We are skipping the external authentication with the card (2-key DES3 is a joke anyway), but we are getting the same decipher so from these logs it is not clear to me what the outlook does not like on the decipher answer from OpenSC that it is getting from the official driver.
(I see that it does the decrypt twice with the same data for some reason in both of the cases)

Next step would be probably looking into the outlook errors/log if they have some better description why and how it failed to decrypt the particular emails with opensc.

The thing is that it looks like the mails themselves are not encrypted with the keys on the card, but the key decrypts just some another key that is used to encrypt the mail itself inside of outlook. And given that this operation is happening outside of the opensc/minidriver/atos driver, it might be that the mail was encrypted with some expired key that the atos driver is somehow caching and providing off-band.

I think it would help to identify whats different in these emails from the ones that work well.

from opensc.

dengert avatar dengert commented on July 18, 2024

Actually the above comment appears to have been fixed in db41cd9 in 0.21.0.

It would still be helpful to know the modulus for this key.

from opensc.

RufusJWB avatar RufusJWB commented on July 18, 2024

RSA raw decryption should return 256 bytes. There is a 1 in 256 chance the first byte may be 0x00. The above logs look like they return 255 bytes and the 2 status bytes. Could their card strips leading zeros in response and their driver handles this but OpenSC does not? The modulus and results are treated as big numbers.

If the modulus for this key has a few leading zero bit too, which limits the size of the input data to the modulus and thus the size of the decrypted data to, change the probability of leading zero bits . What is modules for this key?

Indeed, the modulus of the public key starts with two leading zeros:

Subject Public Key Info:

            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:8a:e3:98:5a:a0:5f:51:76:b4:0a:72:3a:2c:c7:
                    8c:89:17:ed:b5:73:9a:9b:e7:15:cc:22:ec:f8:eb:
                    67:a4:b0:50:c6:be:bd:c4:a9:dd:d9:c8:78:49:b7:
                    45:1e:00:13:7f:4f:c6:bf:84:b1:56:a7:43:36:5e:
                    66:ae:22:bc:be:a7:1a:1d:4a:f6:cd:89:9b:4b:b8:
                    ed:92:00:d3:40:a0:6a:07:59:cd:11:ae:b4:a9:3c:
                    10:35:64:7b:15:96:3f:85:b1:8a:9f:6a:c3:af:07:
                    8b:b3:b7:9d:01:2e:95:b0:d8:f1:db:93:8c:cf:e1:
                    29:36:4a:93:ec:a8:7c:57:8c:06:c4:51:3d:95:3c:
                    65:bd:f7:27:28:22:31:3d:15:15:8c:d4:a8:8a:f4:
                    0a:dc:ee:46:26:0e:62:1c:75:78:7d:63:fd:b7:83:
                    ba:87:45:fa:71:62:bc:48:85:74:63:d6:5c:c5:2e:
                    46:d0:c2:5c:ad:6e:57:65:33:6f:a1:5c:7e:ef:7a:
                    9d:b4:f3:c8:b1:be:d6:2a:03:00:5a:78:25:84:a9:
                    42:5f:fc:a2:6d:81:24:1d:eb:86:68:9c:7c:1f:ec:
                    30:a2:eb:ee:4b:1b:b9:02:7d:22:06:91:0f:0c:f7:
                    12:15:3d:53:71:72:1d:43:fc:15:9b:a5:29:1f:b5:
                    2e:87
                Exponent: 65537 (0x10001)

from opensc.

dengert avatar dengert commented on July 18, 2024

The SPKI looks OK.

A Subject Public key info has asn1 as: https://www.rfc-editor.org/rfc/rfc5912
SubjectPublicKeyInfo {PUBLIC-KEY: IOSet} ::= SEQUENCE {
algorithm AlgorithmIdentifier {PUBLIC-KEY, {IOSet}},
subjectPublicKey BIT STRING
}

Search for: "layman's guide to asn.1" 1993 from a number of different sites:
An ASN.1 DER BIT STRING has: "In a primitive
encoding, the first contents octet gives the number of bits
by which the length of the bit string is less than the next
multiple of eight (this is called the "number of unused
bits")

So the leading 00 says no unused bits. The number of bytes the BIT STRING is (15 * 17) + 2 = 257 one of which is the leading zero.

from opensc.

RufusJWB avatar RufusJWB commented on July 18, 2024

Can you run certutil -v -scinfo using the OpenSC driver?

Of course:

scinfo with CardOS

scinfo with OpenSC

scinfo without any middleware

from opensc.

RufusJWB avatar RufusJWB commented on July 18, 2024

I'm now able to reproduce this behavior without MS Outlook.

This little c# program can decrypt the CMS content of the problematic email if CardOS is installed

string smimeContent = File.ReadAllText(@"encrypted.p7m");

System.Security.Cryptography.Pkcs.EnvelopedCms envelopedCMS = new();

try
{
    envelopedCMS.Decode(Convert.FromBase64String(smimeContent));
    envelopedCMS.Decrypt();

    System.Security.Cryptography.Pkcs.ContentInfo? decryptedByteContent = envelopedCMS?.ContentInfo;
    byte[]? decryptedBytes = decryptedByteContent?.Content;

    string decryptedText = System.Text.Encoding.ASCII.GetString(decryptedBytes);

    Console.WriteLine($"Decrypted content: {decryptedText}");
}
catch (Exception ex)
{
    Console.WriteLine($"Exception: {ex}");
}

but throws this exception if OpenSC is installed.

Exception: System.Security.Cryptography.CryptographicException: The enveloped-data message does not contain the specified recipient.
at System.Security.Cryptography.Pkcs.EnvelopedCms.DecryptContent(RecipientInfoCollection recipientInfos, X509Certificate2Collection extraStore)
at System.Security.Cryptography.Pkcs.EnvelopedCms.Decrypt()
at Program.

$(String[] args) in C:\Users\z002m76a\Repositories\SMIMEDecodeRepro\SMIMEDecodeRepro\Program.cs:line 45

from opensc.

Jakuje avatar Jakuje commented on July 18, 2024

Running simple diff on the logs, I see the following error in the OpenSC log:

ERROR: Could not verify certificate public key against private key

Which is missing on in case the CardOS driver, where it says:

Private key verifies

For all certificate keys

Similar for the another test:

Performing public key matching test...
Public key matching test succeeded

where OpenSC fails:

AES256+RSAES_OAEP(RSA:CNG) test FAILED: Cannot find the certificate and private key to use for decryption. 0x8009200c (-2146885620 CRYPT_E_NO_DECRYPT_CERT)

And CardOS driver works

AES256+RSAES_OAEP(RSA:CNG) test passed

Last test is failing for both cases, but it is unrelated as it is a "Windows Hello for Business 1" "reader".

I think we checked already that the communication with the card matches and the decipher looks like returning the same deciphered data from the minidriver. The key containers are named differently so I am afraid there might be some caching involved in the windows side, which might be messing up the results (for example if the tool will try to verify cached certificate with non-matching key on the card). Do you have a chance to either try on fresh windows installation without the atos driver or check if the cache can be somehow cleaned up?

from opensc.

dengert avatar dengert commented on July 18, 2024

You can delete certificates for the cert store using certutil, MMC's certificate snap-in or Control Panel->Internet Options->Content->Certificates. The user certificates are under Personal and can be removed.

The Container ID's for certificate (stored in the cache) is used to find the card with the private key. But if stored by one driver the other driver can not find the matching key on the card.

from opensc.

RufusJWB avatar RufusJWB commented on July 18, 2024

You can delete certificates for the cert store using certutil, MMC's certificate snap-in or Control Panel->Internet Options->Content->Certificates. The user certificates are under Personal and can be removed.

The Container ID's for certificate (stored in the cache) is used to find the card with the private key. But if stored by one driver the other driver can not find the matching key on the card.

I deleted the certificates using the MMC snap-in, but the problem is still there. Next step for me is trying to replicate this on a different machine. I'll try to find a computer with a Windows directly off the shelf. This might take some days...

from opensc.

RufusJWB avatar RufusJWB commented on July 18, 2024

fyi: I identified a bug / strange behavior in the dotnet framework, that was hiding the true error message. I described it here: dotnet/runtime#94769

At the end, I was able to locate the problematic call inside of this method:

internal static unsafe partial class Interop
{
    internal static unsafe partial class Crypt32
    {
        [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator", "7.0.8.31807")]
        [System.Runtime.CompilerServices.SkipLocalsInitAttribute]
        internal static partial bool CryptMsgControl(global::Microsoft.Win32.SafeHandles.SafeCryptMsgHandle hCryptMsg, int dwFlags, global::Interop.Crypt32.MsgControlType dwCtrlType, ref global::Interop.Crypt32.CMSG_CTRL_DECRYPT_PARA pvCtrlPara)
        {
            int __lastError;
            System.IntPtr __hCryptMsg_native = default;
            bool __retVal;
            int __retVal_native = default;
            // Setup - Perform required setup.
            bool hCryptMsg__addRefd = false;
            try
            {
                // Marshal - Convert managed data to native data.
                hCryptMsg.DangerousAddRef(ref hCryptMsg__addRefd);
                __hCryptMsg_native = hCryptMsg.DangerousGetHandle();
                // Pin - Pin data in preparation for calling the P/Invoke.
                fixed (global::Interop.Crypt32.CMSG_CTRL_DECRYPT_PARA* __pvCtrlPara_native = &pvCtrlPara)
                {
                    System.Runtime.InteropServices.Marshal.SetLastSystemError(0);
                    __retVal_native = __PInvoke(__hCryptMsg_native, dwFlags, dwCtrlType, __pvCtrlPara_native);
                    __lastError = System.Runtime.InteropServices.Marshal.GetLastSystemError();
                }

                // Unmarshal - Convert native data to managed data.
                __retVal = __retVal_native != 0;
            }
            finally
            {
                // Cleanup - Perform required cleanup.
                if (hCryptMsg__addRefd)
                    hCryptMsg.DangerousRelease();
            }

            System.Runtime.InteropServices.Marshal.SetLastPInvokeError(__lastError);
            return __retVal;
            // Local P/Invoke
            [System.Runtime.InteropServices.DllImportAttribute("crypt32.dll", EntryPoint = "CryptMsgControl", ExactSpelling = true)]
            static extern unsafe int __PInvoke(System.IntPtr hCryptMsg, int dwFlags, global::Interop.Crypt32.MsgControlType dwCtrlType, global::Interop.Crypt32.CMSG_CTRL_DECRYPT_PARA* pvCtrlPara);
        }
    }
}

This call fails
__retVal_native = __PInvoke(__hCryptMsg_native, dwFlags, dwCtrlType, __pvCtrlPara_native);
and results in __lastError set to -1073741811
__lastError = System.Runtime.InteropServices.Marshal.GetLastSystemError();

from opensc.

RufusJWB avatar RufusJWB commented on July 18, 2024

I'll try to find a computer with a Windows directly off the shelf. This might take some days...

I've been able to reproduce this issue on a fresh-off-the-shelf Win11 computer. Do you need any additional log files?

from opensc.

dengert avatar dengert commented on July 18, 2024

What is the true error message?

Run with OpenSC minidriver and get the OpenSC MD log.

Also try: pkcs11-tool -login -O to list all objects on cards.
and pkcs11-tool --login --test which does not use the minidriver, by will test the keys on the card.

Also look at opensc.conf https://github.com/OpenSC/OpenSC/blob/master/etc/opensc.conf.example.in for md_guid_* variables.

from opensc.

RufusJWB avatar RufusJWB commented on July 18, 2024

Run with OpenSC minidriver and get the OpenSC MD log.

https://gist.github.com/RufusJWB/b1b2183421eb9df81686237262f65f68

Also try: pkcs11-tool -login -O to list all objects on cards.

https://gist.github.com/RufusJWB/b3fa26d5ba02ea7cc6fd6e649ff23bc8

and pkcs11-tool --login --test

https://gist.github.com/RufusJWB/9f407007af026f148b3b654899589ef3

from opensc.

RufusJWB avatar RufusJWB commented on July 18, 2024

Thank you so much for your analysis. If you could apply this patch and compile a new release candidate, I'd be happy to test it.

from opensc.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.