public static void EncodeUnsealed() { Pkcs12Builder builder = new Pkcs12Builder(); Assert.False(builder.IsSealed); Assert.Throws <InvalidOperationException>(() => builder.Encode()); Assert.Throws <InvalidOperationException>(() => builder.TryEncode(Span <byte> .Empty, out _)); }
public static void EncodeAndTryEncode(Pkcs12IntegrityMode mode) { Pkcs12Builder builder1 = new Pkcs12Builder(); Pkcs12Builder builder2 = new Pkcs12Builder(); Pkcs12SafeContents contents = new Pkcs12SafeContents(); contents.AddSecret(s_zeroOid, s_derNull); builder1.AddSafeContentsUnencrypted(contents); builder2.AddSafeContentsUnencrypted(contents); int macTrailerLength = 0; if (mode == Pkcs12IntegrityMode.Password) { builder1.SealWithMac(ReadOnlySpan <char> .Empty, HashAlgorithmName.SHA1, 2); builder2.SealWithMac(ReadOnlySpan <char> .Empty, HashAlgorithmName.SHA1, 2); // Two OCTET STRINGs of 20 bytes, and the INTEGER 2 macTrailerLength = 2 + 20 + 2 + 20 + 2 + 3; } else if (mode == Pkcs12IntegrityMode.None) { builder1.SealWithoutIntegrity(); builder2.SealWithoutIntegrity(); } Assert.True(builder1.IsSealed, "builder1.IsSealed"); Assert.True(builder2.IsSealed, "builder2.IsSealed"); byte[] encoded = builder1.Encode(); byte[] buf = new byte[encoded.Length + 40]; Span <byte> bufSpan = buf; // Span too small Assert.False(builder2.TryEncode(buf.AsSpan(0, encoded.Length - 1), out int bytesWritten)); Assert.Equal(0, bytesWritten); // Span exactly right bufSpan.Fill(0xCA); Assert.True(builder2.TryEncode(buf.AsSpan(1, encoded.Length), out bytesWritten)); Assert.Equal(encoded.Length, bytesWritten); Assert.Equal(0xCA, buf[0]); Assert.Equal(0xCA, buf[bytesWritten + 1]); if (mode == Pkcs12IntegrityMode.Password) { Assert.Equal(0x02, buf[bytesWritten]); } // The same contents except the MAC (different random salt) Assert.Equal( encoded.AsSpan(0, bytesWritten - macTrailerLength).ByteArrayToHex(), buf.AsSpan(1, bytesWritten - macTrailerLength).ByteArrayToHex()); if (macTrailerLength > 0) { Assert.NotEqual( encoded.AsSpan(bytesWritten - macTrailerLength).ByteArrayToHex(), buf.AsSpan(1 + bytesWritten - macTrailerLength, macTrailerLength).ByteArrayToHex()); } // Span larger than needed bufSpan.Fill(0xCA); Assert.True(builder2.TryEncode(buf.AsSpan(2), out bytesWritten)); Assert.Equal(encoded.Length, bytesWritten); Assert.Equal(0xCA, buf[0]); Assert.Equal(0xCA, buf[1]); Assert.Equal(0xCA, buf[bytesWritten + 2]); if (mode == Pkcs12IntegrityMode.Password) { Assert.Equal(0x02, buf[bytesWritten + 1]); } // The same contents except the MAC (different random salt) Assert.Equal( encoded.AsSpan(0, bytesWritten - macTrailerLength).ByteArrayToHex(), buf.AsSpan(2, bytesWritten - macTrailerLength).ByteArrayToHex()); if (macTrailerLength > 0) { Assert.NotEqual( encoded.AsSpan(bytesWritten - macTrailerLength).ByteArrayToHex(), buf.AsSpan(2 + bytesWritten - macTrailerLength, macTrailerLength).ByteArrayToHex()); } }