public void OneCert_TwentyKeys_NoMatches() { string pw = nameof(OneCert_NoKey_WithLocalKeyId); using (var cert = new X509Certificate2(TestData.MsCertificate)) using (RSA rsa = RSA.Create(TestData.RsaBigExponentParams)) { Pkcs12Builder builder = new Pkcs12Builder(); Pkcs12SafeContents certContents = new Pkcs12SafeContents(); Pkcs12SafeContents keyContents = new Pkcs12SafeContents(); Pkcs12CertBag certBag = certContents.AddCertificate(cert); certBag.Attributes.Add(s_keyIdOne); byte[] keyExport = rsa.ExportEncryptedPkcs8PrivateKey(pw, s_windowsPbe); for (int i = 0; i < 20; i++) { Pkcs12SafeBag keyBag = new Pkcs12ShroudedKeyBag(keyExport, skipCopy: true); keyContents.AddSafeBag(keyBag); // Even with i=1 this won't match, because { 0x01 } != { 0x01, 0x00, 0x00, 0x00 } and // { 0x01 } != { 0x00, 0x00, 0x00, 0x01 } (binary comparison, not "equivalence" comparison). keyBag.Attributes.Add(new Pkcs9LocalKeyId(BitConverter.GetBytes(i))); } AddContents(keyContents, builder, pw, encrypt: false); AddContents(certContents, builder, pw, encrypt: true); builder.SealWithMac(pw, s_digestAlgorithm, MacCount); byte[] pfxBytes = builder.Encode(); ReadPfx(pfxBytes, pw, cert); } }
public static void AddBagDisallowedInReadOnly() { Pkcs12SafeContents contents = MakeReadonly(new Pkcs12SafeContents()); Pkcs12CertBag certBag = new Pkcs12CertBag(s_zeroOid, s_derNull); Assert.True(contents.IsReadOnly); Assert.Throws <InvalidOperationException>(() => contents.AddSafeBag(certBag)); }
public void OneCert_ExtraKeyBadEncoding(bool badTag) { string pw = nameof(OneCert_ExtraKeyBadEncoding); using (var cert = new X509Certificate2(TestData.MsCertificate)) { Pkcs12Builder builder = new Pkcs12Builder(); Pkcs12SafeContents certContents = new Pkcs12SafeContents(); Pkcs12SafeContents keyContents = new Pkcs12SafeContents(); // SEQUENCE { INTEGER(1) } is not a valid RSAPrivateKey, it should be // SEQUENCE { INTEGER(N), INTEGER(E), ... (D, P, Q, DP, DQ, QInv) } // So the conclusion is "unexpected end of data" byte[] badKeyBytes = { 0x30, 0x03, 0x02, 0x01, 0x01 }; // In "badTag" we make the INTEGER be OCTET STRING, triggering a different // "uh, I can't read this..." error. if (badTag) { badKeyBytes[2] = 0x04; } Pkcs8PrivateKeyInfo pk8 = new Pkcs8PrivateKeyInfo( // The correct RSA OID. new Oid("1.2.840.113549.1.1.1", null), null, badKeyBytes, skipCopies: true); // Note that neither the cert nor the key have a LocalKeyId attribute. // The existence of this unreadable key is enough to abort the load on older Windows keyContents.AddSafeBag(new Pkcs12ShroudedKeyBag(pk8.Encrypt(pw, s_windowsPbe))); certContents.AddCertificate(cert); AddContents(keyContents, builder, pw, encrypt: false); AddContents(certContents, builder, pw, encrypt: true); builder.SealWithMac(pw, s_digestAlgorithm, MacCount); byte[] pfxBytes = builder.Encode(); if (s_loaderFailsKeysEarly) { // CRYPT_E_ASN1_BADTAG or CRYPT_E_ASN1_EOD int expectedWin32Error = badTag ? -2146881269 : -2146881278; ReadUnreadablePfx( pfxBytes, pw, expectedWin32Error); } else { ReadPfx(pfxBytes, pw, cert); } } }
public static void AddBagDisallowsNull(bool forReadOnly) { Pkcs12SafeContents contents = new Pkcs12SafeContents(); if (forReadOnly) { contents = MakeReadonly(contents); } AssertExtensions.Throws <ArgumentNullException>( "safeBag", () => contents.AddSafeBag(null)); }
public void OneCorruptCert() { string pw = nameof(OneCorruptCert); Pkcs12Builder builder = new Pkcs12Builder(); Pkcs12SafeContents contents = new Pkcs12SafeContents(); contents.AddSafeBag(new Pkcs12CertBag(new Oid("1.2.840.113549.1.9.22.1"), new byte[] { 0x05, 0x00 })); AddContents(contents, builder, pw, encrypt: true); builder.SealWithMac(pw, s_digestAlgorithm, MacCount); byte[] pfxBytes = builder.Encode(); ReadUnreadablePfx( pfxBytes, pw, // CRYPT_E_BAD_ENCODE -2146885630); }
public void OneCert_ExtraKeyWithUnknownAlgorithm() { string pw = nameof(OneCert_ExtraKeyWithUnknownAlgorithm); using (var cert = new X509Certificate2(TestData.MsCertificate)) { Pkcs12Builder builder = new Pkcs12Builder(); Pkcs12SafeContents certContents = new Pkcs12SafeContents(); Pkcs12SafeContents keyContents = new Pkcs12SafeContents(); Pkcs8PrivateKeyInfo pk8 = new Pkcs8PrivateKeyInfo( // The Microsoft organization OID, not an algorithm. new Oid("1.3.6.1.4.1.311", null), null, new byte[] { 0x05, 0x00 }); // Note that neither the cert nor the key have a LocalKeyId attribute. // The existence of this unknown key is enough to abort the load on older Windows. keyContents.AddSafeBag(new Pkcs12ShroudedKeyBag(pk8.Encrypt(pw, s_windowsPbe))); certContents.AddCertificate(cert); AddContents(keyContents, builder, pw, encrypt: false); AddContents(certContents, builder, pw, encrypt: true); builder.SealWithMac(pw, s_digestAlgorithm, MacCount); byte[] pfxBytes = builder.Encode(); if (s_loaderFailsKeysEarly) { ReadUnreadablePfx( pfxBytes, pw, //NTE_BAD_ALGID, win32Error: -2146893816); } else { ReadPfx(pfxBytes, pw, cert); } } }
public static void WriteCustomType() { Pkcs12SafeContents contents = new Pkcs12SafeContents(); contents.AddSafeBag(new CustomBagType(2)); Pkcs12Builder builder = new Pkcs12Builder(); builder.AddSafeContentsUnencrypted(contents); builder.SealWithoutIntegrity(); byte[] encoded = builder.Encode(); const string expectedHex = "3033020103302E06092A864886F70D010701A021041F301D301B06092A864886" + "F70D010701A00E040C300A3008060100A003040102"; Assert.Equal( expectedHex, encoded.ByteArrayToHex()); }
public static void CopyCustomType() { const string startHex = "3033020103302E06092A864886F70D010701A021041F301D301B06092A864886" + "F70D010701A00E040C300A3008060100A003040102"; Pkcs12Info info = Pkcs12Info.Decode(startHex.HexToByteArray(), out _, skipCopy: true); // This next line implicitly asserts no encryption, and a couple of Single Pkcs12SafeBag bag = info.AuthenticatedSafe.Single().GetBags().Single(); Pkcs12SafeContents contents = new Pkcs12SafeContents(); contents.AddSafeBag(bag); Pkcs12Builder builder = new Pkcs12Builder(); builder.AddSafeContentsUnencrypted(contents); builder.SealWithoutIntegrity(); byte[] encoded = builder.Encode(); Assert.Equal(startHex, encoded.ByteArrayToHex()); }