| 1 | module asn1 |
| 2 | |
| 3 | import encoding.hex |
| 4 | import crypto.pem |
| 5 | |
| 6 | fn test_rsa_public_key() ! { |
| 7 | // from https://asecuritysite.com/digitalcert/sigs4cd |
| 8 | /* |
| 9 | // from https://asecuritysite.com/ecc/sigs4?a0=30819f300d06092a864886f70d010101050003818d0030818902818100a399caf6d93b62a6b6a5311efe93c4d647397ca05a98fa5cddb72d6816ab16fc85f940efe9cf2233975c8925c60f4cd356767cc8445686313a0caeae32930070ca90591a1b249c2fcef9280f5a11d8f1990579d86a05b2523f52c4a876da2d635ca27fbff195e6f7015f834928f033a20b2cd0216a852958b3e58d0f9bd542330203010001 |
| 10 | DER: 30819f300d06092a864886f70d010101050003818d0030818902818100a399caf6d93b62a6b6a5311efe93c4d647397ca05a98fa5cddb72d6816ab16fc85f940efe9cf2233975c8925c60f4cd356767cc8445686313a0caeae32930070ca90591a1b249c2fcef9280f5a11d8f1990579d86a05b2523f52c4a876da2d635ca27fbff195e6f7015f834928f033a20b2cd0216a852958b3e58d0f9bd542330203010001 |
| 11 | |
| 12 | [U] SEQUENCE (30) |
| 13 | [U] SEQUENCE (30) |
| 14 | [U] OBJECT (06): 1.2.840.113549.1.1.1 - RSA Encryption |
| 15 | [U] NULL: None |
| 16 | [U] BIT STRING (03): 0xb'0030818902818100A399CAF6D93B62A6B6A5311EFE93C4D647397CA05A98FA5CDDB72D6816AB16FC85F940EFE9CF2233975C8925C60F4CD356767CC8445686313A0CAEAE32930070CA90591A1B249C2FCEF9280F5A11D8F1990579D86A05B2523F52C4A876DA2D635CA27FBFF195E6F7015F834928F033A20B2CD0216A852958B3E58D0F9BD542330203010001' |
| 17 | 81 |
| 18 | RSA Modulus (1024) bits: a399caf6d93b62a6b6a5311efe93c4d647397ca05a98fa5cddb72d6816ab16fc85f940efe9cf2233975c8925c60f4cd356767cc8445686313a0caeae32930070ca90591a1b249c2fcef9280f5a11d8f1990579d86a05b2523f52c4a876da2d635ca27fbff195e6f7015f834928f033a20b2cd0216a852958b3e58d0f9bd54233 |
| 19 | RSA e: 10001 |
| 20 | |
| 21 | -----BEGIN PUBLIC KEY----- |
| 22 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjmcr22TtipralMR7+k8TWRzl8oFqY+lzdty1oFqsW/IX5QO/pzyIzl1yJJcYPTNNWdnzIRFaGMToMrq4ykwBwypBZGhsknC/O+SgPWhHY8ZkFedhqBbJSP1LEqHbaLWNcon+/8ZXm9wFfg0ko8DOiCyzQIWqFKViz5Y0Pm9VCMwIDAQAB |
| 23 | -----END PUBLIC KEY----- |
| 24 | */ |
| 25 | data := '30819f300d06092a864886f70d010101050003818d0030818902818100a399caf6d93b62a6b6a5311efe93c4d647397ca05a98fa5cddb72d6816ab16fc85f940efe9cf2233975c8925c60f4cd356767cc8445686313a0caeae32930070ca90591a1b249c2fcef9280f5a11d8f1990579d86a05b2523f52c4a876da2d635ca27fbff195e6f7015f834928f033a20b2cd0216a852958b3e58d0f9bd542330203010001' |
| 26 | |
| 27 | bytes := hex.decode(data)! |
| 28 | seq, n := Sequence.decode(bytes)! |
| 29 | |
| 30 | els := seq.fields() |
| 31 | assert els.len == 2 |
| 32 | assert els[0] is Sequence |
| 33 | assert els[1] is BitString |
| 34 | |
| 35 | els0 := els[0] as Sequence |
| 36 | assert els0.fields.len == 2 |
| 37 | assert els0.fields[0] is ObjectIdentifier |
| 38 | oid := els0.fields[0] as ObjectIdentifier |
| 39 | assert oid.str() == '1.2.840.113549.1.1.1' |
| 40 | assert els0.fields[1] is Null |
| 41 | } |
| 42 | |
| 43 | // NOTE: Need to be fixed |
| 44 | fn test_x25519_private_key() ! { |
| 45 | // taken from https://www.rfc-editor.org/rfc/rfc8410#section-10 |
| 46 | // 10.3 Examples of Ed25519 Private Key |
| 47 | |
| 48 | data := '-----BEGIN PRIVATE KEY----- |
| 49 | MC4CAQAwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC |
| 50 | -----END PRIVATE KEY-----' |
| 51 | |
| 52 | // The same item dumped as asn1 yields: |
| 53 | /* |
| 54 | 0 30 46: SEQUENCE { |
| 55 | 2 02 1: INTEGER 0 |
| 56 | 5 30 5: SEQUENCE { |
| 57 | 7 06 3: OBJECT IDENTIFIER |
| 58 | : Ed 25519 signature algorithm { 1 3 101 112 } |
| 59 | : } |
| 60 | 12 04 34: OCTET STRING |
| 61 | : 04 20 D4 EE 72 DB F9 13 58 4A D5 B6 D8 F1 F7 69 |
| 62 | : F8 AD 3A FE 7C 28 CB F1 D4 FB E0 97 A8 8F 44 75 |
| 63 | : 58 42 |
| 64 | : } |
| 65 | */ |
| 66 | block, _ := pem.decode(data)? |
| 67 | |
| 68 | seq, n := Sequence.decode(block.data)! |
| 69 | |
| 70 | assert seq.payload()!.len == 46 |
| 71 | |
| 72 | els := seq.fields() |
| 73 | assert els[0] is Integer |
| 74 | assert els[1] is Sequence |
| 75 | b := els[1] as Sequence |
| 76 | |
| 77 | assert b.fields()[0] is ObjectIdentifier |
| 78 | assert b.fields()[0].length()! == 3 |
| 79 | |
| 80 | oid := b.fields()[0] as ObjectIdentifier |
| 81 | assert oid.str() == '1.3.101.112' |
| 82 | |
| 83 | assert els[2] is OctetString |
| 84 | assert els[2].payload()!.len == 34 |
| 85 | } |
| 86 | |
| 87 | /* |
| 88 | // NEED TO BE FIXED |
| 89 | // TODO: This test still failed on `Sequence.parse_contents` with error `next: truncated bytes` |
| 90 | // FIXME: need to be investigated, bad data, or sequence handling or others source of fail |
| 91 | // so just disable this test, would be moved into related module when ready |
| 92 | fn test_example_x25519_certificate() { |
| 93 | // taken from https://www.rfc-editor.org/rfc/rfc8410.html#section-10 |
| 94 | // 10.2. Example X25519 Certificate |
| 95 | data := '-----BEGIN CERTIFICATE----- |
| 96 | MIIBLDCB36ADAgECAghWAUdKKo3DMDAFBgMrZXAwGTEXMBUGA1UEAwwOSUVURiBUZX |
| 97 | N0IERlbW8wHhcNMTYwODAxMTIxOTI0WhcNNDAxMjMxMjM1OTU5WjAZMRcwFQYDVQQD |
| 98 | DA5JRVRGIFRlc3QgRGVtbzAqMAUGAytlbgMhAIUg8AmJMKdUdIt93LQ+91oNvzoNJj |
| 99 | ga9OukqY6qm05qo0UwQzAPBgNVHRMBAf8EBTADAQEAMA4GA1UdDwEBAAQEAwIDCDAg |
| 100 | BgNVHQ4BAQAEFgQUmx9e7e0EM4Xk97xiPFl1uQvIuzswBQYDK2VwA0EAryMB/t3J5v |
| 101 | /BzKc9dNZIpDmAgs3babFOTQbs+BolzlDUwsPrdGxO3YNGhW7Ibz3OGhhlxXrCe1Cg |
| 102 | w1AH9efZBw== |
| 103 | -----END CERTIFICATE-----' |
| 104 | |
| 105 | // The same item dumped as asn1 yields: |
| 106 | /* |
| 107 | 0 300: SEQUENCE { |
| 108 | 4 223: SEQUENCE { |
| 109 | 7 3: [0] { |
| 110 | 9 1: INTEGER 2 |
| 111 | : } |
| 112 | 12 8: INTEGER 56 01 47 4A 2A 8D C3 30 |
| 113 | 22 5: SEQUENCE { |
| 114 | 24 3: OBJECT IDENTIFIER |
| 115 | : Ed 25519 signature algorithm { 1 3 101 112 } |
| 116 | : } |
| 117 | 29 25: SEQUENCE { |
| 118 | 31 23: SET { |
| 119 | 33 21: SEQUENCE { |
| 120 | 35 3: OBJECT IDENTIFIER commonName (2 5 4 3) |
| 121 | 40 14: UTF8String 'IETF Test Demo' |
| 122 | : } |
| 123 | : } |
| 124 | : } |
| 125 | 56 30: SEQUENCE { |
| 126 | 58 13: UTCTime 01/08/2016 12:19:24 GMT |
| 127 | 73 13: UTCTime 31/12/2040 23:59:59 GMT |
| 128 | : } |
| 129 | 88 25: SEQUENCE { |
| 130 | 90 23: SET { |
| 131 | 92 21: SEQUENCE { |
| 132 | 94 3: OBJECT IDENTIFIER commonName (2 5 4 3) |
| 133 | 99 14: UTF8String 'IETF Test Demo' |
| 134 | : } |
| 135 | : } |
| 136 | : } |
| 137 | 115 42: SEQUENCE { |
| 138 | 117 5: SEQUENCE { |
| 139 | 119 3: OBJECT IDENTIFIER |
| 140 | : ECDH 25519 key agreement { 1 3 101 110 } |
| 141 | : } |
| 142 | 124 33: BIT STRING |
| 143 | : 85 20 F0 09 89 30 A7 54 74 8B 7D DC B4 3E F7 5A |
| 144 | : 0D BF 3A 0D 26 38 1A F4 EB A4 A9 8E AA 9B 4E 6A |
| 145 | : } |
| 146 | 159 69: [3] { |
| 147 | 161 67: SEQUENCE { |
| 148 | 163 15: SEQUENCE { |
| 149 | 165 3: OBJECT IDENTIFIER basicConstraints (2 5 29 19) |
| 150 | 170 1: BOOLEAN TRUE |
| 151 | 173 5: OCTET STRING, encapsulates { |
| 152 | 175 3: SEQUENCE { |
| 153 | 177 1: BOOLEAN FALSE |
| 154 | : } |
| 155 | : } |
| 156 | : } |
| 157 | 180 14: SEQUENCE { |
| 158 | 182 3: OBJECT IDENTIFIER keyUsage (2 5 29 15) |
| 159 | 187 1: BOOLEAN FALSE |
| 160 | 190 4: OCTET STRING, encapsulates { |
| 161 | 192 2: BIT STRING 3 unused bits |
| 162 | : '10000'B (bit 4) |
| 163 | : } |
| 164 | : } |
| 165 | 196 32: SEQUENCE { |
| 166 | 198 3: OBJECT IDENTIFIER subjectKeyIdentifier (2 5 29 14) |
| 167 | 203 1: BOOLEAN FALSE |
| 168 | 206 22: OCTET STRING, encapsulates { |
| 169 | 208 20: OCTET STRING |
| 170 | : 9B 1F 5E ED ED 04 33 85 E4 F7 BC 62 3C 59 75 |
| 171 | : B9 0B C8 BB 3B |
| 172 | : } |
| 173 | : } |
| 174 | : } |
| 175 | : } |
| 176 | : } |
| 177 | 230 5: SEQUENCE { |
| 178 | 232 3: OBJECT IDENTIFIER |
| 179 | : Ed 25519 signature algorithm { 1 3 101 112 } |
| 180 | : } |
| 181 | 237 65: BIT STRING |
| 182 | : AF 23 01 FE DD C9 E6 FF C1 CC A7 3D 74 D6 48 A4 |
| 183 | : 39 80 82 CD DB 69 B1 4E 4D 06 EC F8 1A 25 CE 50 |
| 184 | : D4 C2 C3 EB 74 6C 4E DD 83 46 85 6E C8 6F 3D CE |
| 185 | : 1A 18 65 C5 7A C2 7B 50 A0 C3 50 07 F5 E7 D9 07 |
| 186 | : } |
| 187 | */ |
| 188 | block, _ := pem.decode(data)? |
| 189 | seq, n := Sequence.decode(block.data)! |
| 190 | |
| 191 | assert seq.payload()!.len == 302 |
| 192 | |
| 193 | // certificate is arrays of 3 element |
| 194 | assert seq.fields().len == 3 |
| 195 | |
| 196 | els := seq.fields() |
| 197 | // last element |
| 198 | assert els[2] is BitString |
| 199 | bts := BitString.from_bytes(seq.fields[2].payload()!)! |
| 200 | exp := [u8(0xAF), 0x23, 0x01, 0xFE, 0xDD, 0xC9, 0xE6, 0xFF, 0xC1, 0xCC, 0xA7, 0x3D, 0x74, 0xD6, |
| 201 | 0x48, 0xA4, 0x39, 0x80, 0x82, 0xCD, 0xDB, 0x69, 0xB1, 0x4E, 0x4D, 0x06, 0xEC, 0xF8, 0x1A, |
| 202 | 0x25, 0xCE, 0x50, 0xD4, 0xC2, 0xC3, 0xEB, 0x74, 0x6C, 0x4E, 0xDD, 0x83, 0x46, 0x85, 0x6E, |
| 203 | 0xC8, 0x6F, 0x3D, 0xCE, 0x1A, 0x18, 0x65, 0xC5, 0x7A, 0xC2, 0x7B, 0x50, 0xA0, 0xC3, 0x50, |
| 204 | 0x07, 0xF5, 0xE7, 0xD9, 0x07] |
| 205 | assert bts.data == exp |
| 206 | } |
| 207 | */ |
| 208 | |