noloader / cryptopp-pem

PEM parsing of keys and parameters for Crypto++ project
42 stars 31 forks source link

Certificate parsing fails when RelativeDistinguishedName contains multiple AttributeTypeAndValue objects #21

Open r0g3r3k opened 4 months ago

r0g3r3k commented 4 months ago

Hello, X509Certificate BERDecode/Load fails when (e.g. subject) RDN SET contains multiple AttributeTypeAndValue values. Usually, each AttributeTypeAndValue is wrapped in separate RDN SET (that hence contains only a single value). But according to the spec (as far as I understand it), the RDN SET may contain more AttributeTypeAndValue values.

Consider following certificate:

30820256308201c3a0030201020229656d616e727553747365540b13040455030612307472654374736554081303045503060f3025312730300906052b0e03021d05003017311530130603550403130c54657374526f6f7443657274301e170d3234303630373130303234345a170d3235303630373136303234345a30273125300f06035504031308546573744365727430120603550404130b546573745375726e616d6530820122300d06092a864886f70d01010105000382010f003082010a028201010092e62baa44416ac0e21f94b0bf4156d1dff2a764d9e8eec2dca43fd5f04dd9fc5ca75fedc8ca9a8a9d9924a4a0a6fec249ea8ecd0279312e6e4322d6ad645406b11b21dbe257e1fbba524c702bae1a06f5b02543d4fae359e7df25c7eec3b086c5e16dd3cd726631f8430c058d54d4caa3742c3d188305cf2377437024db9b8a372b41cb054dc3962c66dd1a83bf0e2019ac5be93373070b18a925862ffe1f7287727cf9b4274ff0615f91d6dc80082bfc8cc17d95c002c7e9d8b92fea3a7369b4339756c1f5eec8b411f251a022ce2664ce1c5293e7b5f6c8e798bea95215e08c67ca6722ec1bc0b25e09e01faceacc06a91f5e4e1481181287f7285d19195d0203010001300906052b0e03021d05000381810063af1155c46f46f2200de6b628bb65382eb95942eeec74f252b8907911dc3979d20347846894fcc6c140499076e6c4d58f08910f92bdac7156e88e0712ad225d1dc3188907d04ce1016b7c8d2ab8fe9886dddaab98e577d47b0326c85683b07e903d4f2d1c34ace306e433ed8886e43b8f5b33b0f9d4c8ead2577e71e8ae93e2

This fails to decode. Adding a while in X509Certificate::BERDecodeDistinguishedName() fixes this:

do
{
  RdnValue value;
  value.BERDecode(set);
  temp.push_back(value);
}
while (!set.EndReached());