using System; using System.Text; using System.IO; using System.Diagnostics; using CryptoSysPKI; // Create keys and X.509 certificates for Alice, Bob and Carl using RSA-PSS and ECDSA signature algorithms // similar to those given in RFC4134 " Examples of S/MIME Messages" namespace SetupAliceBobCarl_PSS_ECDSA { class SetupAliceBobCarl { static void Main(string[] args) { /* // MakeTheKeys(); - only do this once */ //GetUnencryptedPrivateKeys(); MakeCarlRSASelfSigned(); MakeAliceRSA(); MakeBobRSA(); MakeCarlECDSASelfSigned(); MakeAliceECDSA(); } static void MakeCarlRSASelfSigned() { int r; string certfile = "CarlRSAPssSelf.cer"; string dn = "CN=CarlRSA;O=PSS;"; string pubkeyfile = "CarlRSAPSS.pub"; string prikeyfile = "CarlRSAPSS.p8e"; // Compute SubjectKeyIdentifier from public key (see RFC5280 s4.2.1.2) string ski = Hash.HexFromFile(pubkeyfile, HashAlgorithm.Sha1); string extns = "rfc822name=CarlRSA@example.com;" + "serialNumber=47346bc7800056bc11d36e2e9ff25020;" + "subjectKeyIdentifier=" + ski + ";" + "notBefore=2018-04-01;" + "notAfter=2039-12-31;"; X509.KeyUsageOptions ku = X509.KeyUsageOptions.DigitalSignature | X509.KeyUsageOptions.KeyCertSign | X509.KeyUsageOptions.CrlSign; // Make new cert using RSA-PSS but using Pss_SaltLenZero so we get the same result each time r = X509.MakeCertSelf(certfile, prikeyfile, 0, 0, dn, extns, ku, "password", SigAlgorithm.Rsa_Pss_Sha256, X509.CertOptions.Pss_SaltLenZero); if (0 == r) Console.WriteLine("Saved certificate as {0}", certfile); else Console.WriteLine("ERROR {0}: {1}: {2}", r, General.ErrorLookup(r), General.LastError()); Debug.Assert(0 == r); Console.WriteLine("SHA-1 Thumb '{0}'={1}", certfile, X509.CertThumb(certfile, HashAlgorithm.Sha1)); } static void MakeAliceRSA() { int r; string certfile = "AliceRSAPssSignByCarl.cer"; string issuercert = "CarlRSAPssSelf.cer"; string issuerkey = "CarlRSAPSS.p8e"; string subjectpubkey = "AliceRSAPSS.pub"; string dn = "CN=AliceRSA;O=PSS;"; // Compute SubjectKeyIdentifier from public key (see RFC5280 s4.2.1.2) string ski = Hash.HexFromFile(subjectpubkey, HashAlgorithm.Sha1); string extns = "rfc822name=AliceRSA@example.com;" + "serialNumber=47346BC7800056BC11D36E2EC410B3B0;" + "subjectKeyIdentifier=" + ski + ";" + "notBefore=2018-04-01;" + "notAfter=2039-12-31;"; X509.KeyUsageOptions ku = X509.KeyUsageOptions.DigitalSignature | X509.KeyUsageOptions.NonRepudiation; // Make new cert using RSA-PSS but using Pss_SaltLenZero so we get the same result each time r = X509.MakeCert(certfile, issuercert, subjectpubkey, issuerkey, 0, 0, dn, extns, ku, "password", SigAlgorithm.Rsa_Pss_Sha256, X509.CertOptions.Pss_SaltLenZero | X509.CertOptions.AuthKeyId); if (0 == r) Console.WriteLine("Saved certificate as {0}", certfile); else Console.WriteLine("ERROR {0}: {1}: {2}", r, General.ErrorLookup(r), General.LastError()); Debug.Assert(0 == r); Console.WriteLine("SHA-1 Thumb '{0}'={1}", certfile, X509.CertThumb(certfile, HashAlgorithm.Sha1)); Console.WriteLine(X509.TextDumpToString(certfile, 0)); } static void MakeBobRSA() { int r; string certfile = "BobRSAPssSignByCarl.cer"; string issuercert = "CarlRSAPssSelf.cer"; string issuerkey = "CarlRSAPSS.p8e"; string subjectpubkey = "BobRSAPSS.pub"; string dn = "CN=BobRSA-PSS;"; // Compute SubjectKeyIdentifier from public key (see RFC5280 s4.2.1.2) string ski = Hash.HexFromFile(subjectpubkey, HashAlgorithm.Sha1); string extns = "rfc822name=BobRSA@example.com;" + "serialNumber=48346bc7800056bc11d36e2ecd5d71d0;" + "subjectKeyIdentifier=" + ski + ";" + "notBefore=2018-04-01;" + "notAfter=2039-12-31;"; X509.KeyUsageOptions ku = X509.KeyUsageOptions.KeyEncipherment; // Make new cert using RSA-PSS but using Pss_SaltLenZero so we get the same result each time r = X509.MakeCert(certfile, issuercert, subjectpubkey, issuerkey, 0, 0, dn, extns, ku, "password", SigAlgorithm.Rsa_Pss_Sha256, X509.CertOptions.Pss_SaltLenZero | X509.CertOptions.AuthKeyId); if (0 == r) Console.WriteLine("Saved certificate as {0}", certfile); else Console.WriteLine("ERROR {0}: {1}: {2}", r, General.ErrorLookup(r), General.LastError()); Debug.Assert(0 == r); Console.WriteLine("SHA-1 Thumb '{0}'={1}", certfile, X509.CertThumb(certfile, HashAlgorithm.Sha1)); } static void MakeCarlECDSASelfSigned() { int r; string certfile = "CarlEcdsaSelf.cer"; string dn = "CN=CarlECDSA;O=ECC;"; string pubkeyfile = "CarlECCP256.pub"; string prikeyfile = "CarlECCP256.p8e"; // Compute SubjectKeyIdentifier from public key (see RFC5280 s4.2.1.2) string ski = Hash.HexFromFile(pubkeyfile, HashAlgorithm.Sha1); string extns = "rfc822name=CarlECDSA@example.com;" + "serialNumber=a8427780659491799706b6fe62f42d55;" + "subjectKeyIdentifier=" + ski + ";" + "notBefore=2018-04-01;" + "notAfter=2039-12-31;"; X509.KeyUsageOptions ku = X509.KeyUsageOptions.DigitalSignature | X509.KeyUsageOptions.KeyCertSign | X509.KeyUsageOptions.CrlSign; // Make new cert using ECDSA but using Ecdsa_Deterministic so we get the same result each time r = X509.MakeCertSelf(certfile, prikeyfile, 0, 0, dn, extns, ku, "password", SigAlgorithm.Ecdsa_Sha256, X509.CertOptions.Ecdsa_Deterministic); if (0 == r) Console.WriteLine("Saved certificate as {0}", certfile); else Console.WriteLine("ERROR {0}: {1}: {2}", r, General.ErrorLookup(r), General.LastError()); Debug.Assert(0 == r); Console.WriteLine("SHA-1 Thumb '{0}'={1}", certfile, X509.CertThumb(certfile, HashAlgorithm.Sha1)); } static void MakeAliceECDSA() { int r; string certfile = "AliceEcdsaSignByCarl.cer"; string issuercert = "CarlEcdsaSelf.cer"; string issuerkey = "CarlECCP256.p8e"; string subjectpubkey = "AliceECCP256.pub"; string dn = "CN=AliceECDSA;O=ECC;"; // Compute SubjectKeyIdentifier from public key (see RFC5280 s4.2.1.2) string ski = Hash.HexFromFile(subjectpubkey, HashAlgorithm.Sha1); string extns = "rfc822name=AliceECDSA@example.com;" + "serialNumber=08a6263fc85bdeae69d9311a9445c41f;" + "subjectKeyIdentifier=" + ski + ";" + "notBefore=2018-04-01;" + "notAfter=2039-12-31;"; X509.KeyUsageOptions ku = X509.KeyUsageOptions.DigitalSignature | X509.KeyUsageOptions.NonRepudiation; // Make new cert using ECDSA but using Ecdsa_Deterministic so we get the same result each time r = X509.MakeCert(certfile, issuercert, subjectpubkey, issuerkey, 0, 0, dn, extns, ku, "password", SigAlgorithm.Ecdsa_Sha256, X509.CertOptions.Ecdsa_Deterministic | X509.CertOptions.AuthKeyId); if (0 == r) Console.WriteLine("Saved certificate as {0}", certfile); else Console.WriteLine("ERROR {0}: {1}: {2}", r, General.ErrorLookup(r), General.LastError()); Debug.Assert(0 == r); Console.WriteLine("SHA-1 Thumb '{0}'={1}", certfile, X509.CertThumb(certfile, HashAlgorithm.Sha1)); Console.WriteLine(X509.TextDumpToString(certfile, 0)); } static void GetUnencryptedPrivateKeys() { string keystr, newname; int r; // For each .p8e key file, save again as an unencrypted .p8 key string[] rsaKeyFiles = { "AliceRSAPSS.p8e", "BobRSAPSS.p8e", "CarlRSAPSS.p8e" }; foreach (string fname in rsaKeyFiles) { newname = Path.ChangeExtension(fname, ".p8"); Console.WriteLine("{0} --> {1}", fname, newname); keystr = Rsa.ReadPrivateKey(fname, "password").ToString(); Debug.Assert(keystr.Length > 0); r = Rsa.SavePrivateKeyInfo(newname, keystr, 0); if (0 == r) Console.WriteLine("Saved key as {0}", newname); else Console.WriteLine("ERROR {0}: {1}: {2}", r, General.ErrorLookup(r), General.LastError()); } string[] eccKeyFiles = { "AliceECCP256.p8e", "BobECCP256.p8e", "CarlECCP256.p8e" }; foreach (string fname in eccKeyFiles) { newname = Path.ChangeExtension(fname, ".p8"); Console.WriteLine("{0} --> {1}", fname, newname); keystr = Ecc.ReadPrivateKey(fname, "password").ToString(); Debug.Assert(keystr.Length > 0); r = Ecc.SaveKey(newname, keystr, 0, 0); if (0 == r) Console.WriteLine("Saved key as {0}", newname); else Console.WriteLine("ERROR {0}: {1}: {2}", r, General.ErrorLookup(r), General.LastError()); } } static void MakeTheKeys() { // DO ONCE int r; Console.WriteLine("Generating three 2048-bit RSA keys..."); r = Rsa.MakeKeys("AliceRSAPSS.pub", "AliceRSAPSS.p8e", 2048, Rsa.PublicExponent.Exp_EQ_65537, 80, "password", Rsa.PbeOptions.Pbe_Pbkdf2_aes256_CBC, false); r = Rsa.MakeKeys("BobRSAPSS.pub", "BobRSAPSS.p8e", 2048, Rsa.PublicExponent.Exp_EQ_65537, 80, "password", Rsa.PbeOptions.Pbe_Pbkdf2_aes256_CBC, false); r = Rsa.MakeKeys("CarlRSAPSS.pub", "CarlRSAPSS.p8e", 2048, Rsa.PublicExponent.Exp_EQ_65537, 80, "password", Rsa.PbeOptions.Pbe_Pbkdf2_aes256_CBC, false); Console.WriteLine("Generating three ECC keys using P-256..."); r = Ecc.MakeKeys("AliceECCP256.pub", "AliceECCP256.p8e", Ecc.CurveName.P_256, "password", Ecc.PbeScheme.Pbe_Pbkdf2_aes256_CBC, "", 0); r = Ecc.MakeKeys("BobECCP256.pub", "BobECCP256.p8e", Ecc.CurveName.P_256, "password", Ecc.PbeScheme.Pbe_Pbkdf2_aes256_CBC, "", 0); r = Ecc.MakeKeys("CarlECCP256.pub", "CarlECCP256.p8e", Ecc.CurveName.P_256, "password", Ecc.PbeScheme.Pbe_Pbkdf2_aes256_CBC, "", 0); } } }