librasn / rasn

A Safe #[no_std] ASN.1 Codec Framework
Other
195 stars 47 forks source link

Can't parse ContentInfo. #66

Closed ChrisGreenaway closed 2 years ago

ChrisGreenaway commented 2 years ago

I have some data which is supposed to be a ContentInfo (received from AWS KMS), but the following code fails:

let data: Vec<u8> = vec![ 48, 128, 6, 9, 42, 134, 72, 134, 247, 13, 1, 7, 3, 160, 128, 48, 128, 2, 1, 2, 49, 130, 1, 107, 48, 130, 1, 103, 2, 1, 2, 128, 32, 212, 17, 115, 195, 21, 153, 39, 196, 140, 239, 85, 90, 110, 51, 220, 56, 29, 10, 60, 34, 101, 42, 71, 97, 142, 255, 112, 248, 99, 5, 201, 148, 48, 60, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 7, 48, 47, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 4, 130, 1, 0, 17, 238, 11, 93, 44, 255, 28, 111, 215, 103, 19, 197, 237, 193, 145, 116, 70, 103, 208, 137, 8, 71, 74, 138, 141, 169, 169, 238, 40, 84, 122, 21, 216, 49, 63, 90, 105, 66, 69, 178, 78, 28, 66, 236, 23, 81, 214, 78, 0, 210, 182, 109, 105, 36, 16, 214, 250, 246, 112, 244, 33, 164, 75, 118, 120, 18, 29, 71, 174, 23, 38, 95, 37, 244, 10, 75, 229, 177, 41, 169, 74, 68, 183, 204, 187, 113, 244, 225, 65, 222, 187, 86, 224, 102, 147, 85, 248, 213, 228, 192, 93, 127, 5, 184, 123, 196, 165, 110, 16, 248, 25, 242, 194, 38, 156, 219, 100, 43, 167, 72, 184, 66, 34, 225, 225, 216, 104, 156, 247, 26, 150, 12, 151, 202, 76, 173, 179, 197, 118, 217, 109, 245, 52, 171, 99, 177, 28, 138, 137, 206, 246, 175, 166, 254, 119, 86, 66, 141, 227, 120, 66, 76, 120, 93, 186, 204, 38, 91, 48, 34, 107, 23, 191, 92, 251, 246, 248, 112, 227, 238, 122, 165, 22, 18, 94, 232, 208, 209, 129, 1, 6, 28, 235, 238, 198, 204, 221, 234, 17, 111, 190, 163, 148, 215, 140, 71, 132, 48, 37, 169, 178, 25, 196, 20, 9, 240, 39, 137, 22, 40, 71, 155, 200, 59, 244, 156, 220, 212, 154, 94, 211, 132, 198, 195, 245, 49, 89, 152, 238, 178, 200, 226, 193, 145, 28, 175, 31, 179, 137, 30, 168, 96, 210, 208, 54, 181, 48, 128, 6, 9, 42, 134, 72, 134, 247, 13, 1, 7, 1, 48, 29, 6, 9, 96, 134, 72, 1, 101, 3, 4, 1, 42, 4, 16, 171, 84, 103, 126, 243, 106, 225, 202, 106, 15, 104, 146, 100, 201, 219, 97, 160, 128, 4, 48, 75, 109, 64, 64, 47, 137, 225, 83, 92, 88, 253, 78, 185, 232, 53, 253, 41, 237, 32, 149, 221, 227, 20, 25, 156, 80, 137, 130, 53, 140, 158, 244, 110, 86, 121, 214, 90, 195, 21, 63, 0, 86, 150, 198, 189, 2, 120, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
let _content_info: rasn_cms::ContentInfo = rasn::ber::decode(&*data).unwrap();

with the error:

panicked at 'called `Result::unwrap()` on an `Err` value: FieldError { name: "ContentInfo.content", error: "Error in Parser: Parsing Failure: Parsing Error: Error { input: [2, 1, 2, 49, 130, 1, 107, ... , 0, 0], code: Tag }" }'

However, if I define a new struct:

#[derive(rasn::AsnType, Clone, Debug, rasn::Decode, rasn::Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MyContentInfo {
    pub content_type: rasn_cms::ContentType,
    #[rasn(tag(explicit(0)))]
    pub content: rasn_cms::EnvelopedData,
}

then I can decode to that fine. The only change is changing the type of content from Any to EnvelopedData.

ChrisGreenaway commented 2 years ago

So sorry - it's not a ContentInfo after all. I've spent all day thinking it was. It's a RecipientInfo and seems to decode fine. :-)

ChrisGreenaway commented 2 years ago

I'm clearly too tired, please ignore my last comment about RecipientInfo.

XAMPPRocky commented 2 years ago

Thank you for your issue! At a glance I believe the issue might be that the data is that the data uses PKCS#7 EncapsulatedContentInfo rather than CMS' definition. Funnily enough we just had a recent PR adding support for that. Do you want to checkout and try #62 and see if that works for you?

ChrisGreenaway commented 2 years ago

Thanks for your quick response.

The AWS KMS spec says it's using RFC 5652 Section 6.

I tried the following:

rasn = { git = "https://github.com/dvc94ch/rasn", branch = "ms-cms"}
rasn-cms = { git = "https://github.com/dvc94ch/rasn", branch = "ms-cms"}
let content_info: rasn_cms::pkcs7_compat::EncapsulatedContentInfo = rasn::ber::decode(&*data).unwrap();

I get a very similar error:

panicked at 'called `Result::unwrap()` on an `Err` value: Parser { msg: "Parsing Failure: Parsing Error: Error { input: [48, 128, 2, 1, 2, 49, 130, 1, 107, ... , 0, 0], code: Tag }" }'

BTW, some of the data parses to ObjectIdentifier and EnvelopedData fine (with the mainline code):

let _oid: rasn::types::ObjectIdentifier = rasn::ber::decode(&data[2..=12]).unwrap();
let _envelope: rasn_cms::EnvelopedData = rasn::ber::decode(&data[15..data.len()-4]).unwrap();

With that in mind, I've converted the data to hex and broken it into lines:

30 80
  06 09 2A 86 48 86 F7 0D 01 07 03
  A0 80
    30 80 02 01 02 31 82 01 6B 30 82 01 67 02 01 02 80 20 D4 11 73 C3 15 99 27 C4 8C EF 55 5A 6E 33 DC 38 1D 0A 3C 22 65 2A 47 61 8E FF 70 F8 63 05 C9 94 30 3C 06 09 2A 86 48 86 F7 0D 01 01 07 30 2F A0 0F 30 0D 06 09 60 86 48 01 65 03 04 02 01 05 00 A1 1C 30 1A 06 09 2A 86 48 86 F7 0D 01 01 08 30 0D 06 09 60 86 48 01 65 03 04 02 01 05 00 04 82 01 00 11 EE 0B 5D 2C FF 1C 6F D7 67 13 C5 ED C1 91 74 46 67 D0 89 08 47 4A 8A 8D A9 A9 EE 28 54 7A 15 D8 31 3F 5A 69 42 45 B2 4E 1C 42 EC 17 51 D6 4E 00 D2 B6 6D 69 24 10 D6 FA F6 70 F4 21 A4 4B 76 78 12 1D 47 AE 17 26 5F 25 F4 0A 4B E5 B1 29 A9 4A 44 B7 CC BB 71 F4 E1 41 DE BB 56 E0 66 93 55 F8 D5 E4 C0 5D 7F 05 B8 7B C4 A5 6E 10 F8 19 F2 C2 26 9C DB 64 2B A7 48 B8 42 22 E1 E1 D8 68 9C F7 1A 96 0C 97 CA 4C AD B3 C5 76 D9 6D F5 34 AB 63 B1 1C 8A 89 CE F6 AF A6 FE 77 56 42 8D E3 78 42 4C 78 5D BA CC 26 5B 30 22 6B 17 BF 5C FB F6 F8 70 E3 EE 7A A5 16 12 5E E8 D0 D1 81 01 06 1C EB EE C6 CC DD EA 11 6F BE A3 94 D7 8C 47 84 30 25 A9 B2 19 C4 14 09 F0 27 89 16 28 47 9B C8 3B F4 9C DC D4 9A 5E D3 84 C6 C3 F5 31 59 98 EE B2 C8 E2 C1 91 1C AF 1F B3 89 1E A8 60 D2 D0 36 B5 30 80 06 09 2A 86 48 86 F7 0D 01 07 01 30 1D 06 09 60 86 48 01 65 03 04 01 2A 04 10 AB 54 67 7E F3 6A E1 CA 6A 0F 68 92 64 C9 DB 61 A0 80 04 30 4B 6D 40 40 2F 89 E1 53 5C 58 FD 4E B9 E8 35 FD 29 ED 20 95 DD E3 14 19 9C 50 89 82 35 8C 9E F4 6E 56 79 D6 5A C3 15 3F 00 56 96 C6 BD 02 78 EF 00 00 00 00 00 00
  00 00
00 00

So it looks like an indefinite length sequence with the first component as an OID, the second component a context-specific type.

The AWS doc is here: https://github.com/aws/aws-nitro-enclaves-sdk-c/blob/main/docs/kms-apis/Decrypt.md (see CiphertextForRecipient)

There's also a C API that AWS provide for parsing this: https://github.com/aws/aws-nitro-enclaves-sdk-c/blob/main/source/cms.c - the aws_cms_parse_enveloped_data function.

ancwrd1 commented 2 years ago

It doesn't look like a valid CMS structure. Note the non-standard sequence between the recipientInfos and encryptedContentInfo.

openssl cms -inform der -in /tmp/aws-cms.bin -cmsout -print

CMS_ContentInfo: 
  contentType: pkcs7-envelopedData (1.2.840.113549.1.7.3)
  d.envelopedData: 
    version: 2
    originatorInfo: <ABSENT>
    recipientInfos:
      d.ktri: 
        version: 2
        d.subjectKeyIdentifier: 
          0000 - d4 11 73 c3 15 99 27 c4-8c ef 55 5a 6e 33 dc   ..s...'...UZn3.
          000f - 38 1d 0a 3c 22 65 2a 47-61 8e ff 70 f8 63 05   8..<"e*Ga..p.c.
          001e - c9 94                                          ..
        keyEncryptionAlgorithm: 
          algorithm: rsaesOaep (1.2.840.113549.1.1.7)
          parameter: SEQUENCE:
    0:d=0  hl=2 l=  47 cons: SEQUENCE          
    2:d=1  hl=2 l=  15 cons:  cont [ 0 ]        
    4:d=2  hl=2 l=  13 cons:   SEQUENCE          
    6:d=3  hl=2 l=   9 prim:    OBJECT            :sha256
   17:d=3  hl=2 l=   0 prim:    NULL              
   19:d=1  hl=2 l=  28 cons:  cont [ 1 ]        
   21:d=2  hl=2 l=  26 cons:   SEQUENCE          
   23:d=3  hl=2 l=   9 prim:    OBJECT            :mgf1
   34:d=3  hl=2 l=  13 cons:    SEQUENCE          
   36:d=4  hl=2 l=   9 prim:     OBJECT            :sha256
   47:d=4  hl=2 l=   0 prim:     NULL              
        encryptedKey: 
          0000 - 11 ee 0b 5d 2c ff 1c 6f-d7 67 13 c5 ed c1 91   ...],..o.g.....
          000f - 74 46 67 d0 89 08 47 4a-8a 8d a9 a9 ee 28 54   tFg...GJ.....(T
          001e - 7a 15 d8 31 3f 5a 69 42-45 b2 4e 1c 42 ec 17   z..1?ZiBE.N.B..
          002d - 51 d6 4e 00 d2 b6 6d 69-24 10 d6 fa f6 70 f4   Q.N...mi$....p.
          003c - 21 a4 4b 76 78 12 1d 47-ae 17 26 5f 25 f4 0a   !.Kvx..G..&_%..
          004b - 4b e5 b1 29 a9 4a 44 b7-cc bb 71 f4 e1 41 de   K..).JD...q..A.
          005a - bb 56 e0 66 93 55 f8 d5-e4 c0 5d 7f 05 b8 7b   .V.f.U....]...{
          0069 - c4 a5 6e 10 f8 19 f2 c2-26 9c db 64 2b a7 48   ..n.....&..d+.H
          0078 - b8 42 22 e1 e1 d8 68 9c-f7 1a 96 0c 97 ca 4c   .B"...h.......L
          0087 - ad b3 c5 76 d9 6d f5 34-ab 63 b1 1c 8a 89 ce   ...v.m.4.c.....
          0096 - f6 af a6 fe 77 56 42 8d-e3 78 42 4c 78 5d ba   ....wVB..xBLx].
          00a5 - cc 26 5b 30 22 6b 17 bf-5c fb f6 f8 70 e3 ee   .&[0"k..\...p..
          00b4 - 7a a5 16 12 5e e8 d0 d1-81 01 06 1c eb ee c6   z...^..........
          00c3 - cc dd ea 11 6f be a3 94-d7 8c 47 84 30 25 a9   ....o.....G.0%.
          00d2 - b2 19 c4 14 09 f0 27 89-16 28 47 9b c8 3b f4   ......'..(G..;.
          00e1 - 9c dc d4 9a 5e d3 84 c6-c3 f5 31 59 98 ee b2   ....^.....1Y...
          00f0 - c8 e2 c1 91 1c af 1f b3-89 1e a8 60 d2 d0 36   ...........`..6
          00ff - b5                                             .
    encryptedContentInfo: 
      contentType: pkcs7-data (1.2.840.113549.1.7.1)
      contentEncryptionAlgorithm: 
        algorithm: aes-256-cbc (2.16.840.1.101.3.4.1.42)
        parameter: OCTET STRING:
          0000 - ab 54 67 7e f3 6a e1 ca-6a 0f 68 92 64 c9 db   .Tg~.j..j.h.d..
          000f - 61                                             a
      encryptedContent: 
        0000 - 4b 6d 40 40 2f 89 e1 53-5c 58 fd 4e b9 e8 35   Km@@/..S\X.N..5
        000f - fd 29 ed 20 95 dd e3 14-19 9c 50 89 82 35 8c   .). ......P..5.
        001e - 9e f4 6e 56 79 d6 5a c3-15 3f 00 56 96 c6 bd   ..nVy.Z..?.V...
        002d - 02 78 ef                                       .x.
    unprotectedAttrs:
      <ABSENT>
ancwrd1 commented 2 years ago

Nah, I think I am wrong here. It is just a key encryption algorithm.

XAMPPRocky commented 2 years ago

Last time I looked at it, I thought it might be the indefinite length, but I'm not certain.

ancwrd1 commented 2 years ago

Yes the issue is the Decoder::decode_any which doesn't handle indefinite length correctly. In the code below the parse_value returns None as contents but this case is not covered. I tried modifying it similar to parsing the OctetString but the parser was failing still and because I am not much familiar with the code I think a bit more investigation is needed.

    fn decode_any(&mut self) -> Result<types::Any> {
        let (input, _) = self::parser::parse_value(&self.config, self.input, None)?;
        let diff = self.input.len() - input.len();
        let contents = &self.input[..diff];
        self.input = input;

        Ok(types::Any {
            contents: contents.to_vec(),
        })
    }