Pārlūkot izejas kodu

add key constraint

shayne_lo 4 mēneši atpakaļ
vecāks
revīzija
e6cfb0721d

+ 16 - 0
CAUtilLib/AddExtensionData.cs

@@ -0,0 +1,16 @@
+using Org.BouncyCastle.Asn1;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CAUtilLib
+{
+    public class AddExtensionData
+    {
+        public string OID { get; set; }
+        public bool Critical { get; set; }
+        public Asn1Encodable ExtensionValue { get; set; }
+    }
+}

+ 84 - 16
CAUtilLib/BouncyCastleWrapper.cs

@@ -17,6 +17,7 @@ using System.Text;
 using System.Threading.Tasks;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.OpenSsl;
+using static System.Runtime.InteropServices.JavaScript.JSType;
 
 namespace CAUtilLib
 {
@@ -50,7 +51,7 @@ namespace CAUtilLib
             AsymmetricCipherKeyPair issuerKey,
             AsymmetricKeyParameter subjectPublic,
             BigInteger? issuerSerialNumber = null,
-            bool isCertificateAuthority = false)
+            List<AddExtensionData> extensionDatas = null)
         {
             var selfserilaNumber = BigInteger.ProbablePrime(120, secureRandom);
             if (issuerSerialNumber is null)
@@ -60,9 +61,11 @@ namespace CAUtilLib
 
             ISignatureFactory signatureFactory;
             signatureFactory = new Asn1SignatureFactory(
-                PkcsObjectIdentifiers.Sha512WithRsaEncryption.ToString(),
+                PkcsObjectIdentifiers.Sha256WithRsaEncryption.ToString(),
                 issuerKey.Private);
-            signatureFactory = new Asn1SignatureFactory(PkcsObjectIdentifiers.Sha512WithRsaEncryption.ToString(), issuerKey.Private);
+            //signatureFactory = new Asn1SignatureFactory(
+            //    PkcsObjectIdentifiers.Sha512WithRsaEncryption.ToString(),
+            //    issuerKey.Private);
 
             var certGenerator = new X509V3CertificateGenerator();
             certGenerator.SetIssuerDN(issuer);
@@ -84,14 +87,22 @@ namespace CAUtilLib
                     )
                 );
 
-            if (isCertificateAuthority)
+            if (extensionDatas != null)
             {
-                certGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true,
-                    new BasicConstraints(0));
-                //certGenerator.AddExtension(X509Extensions.KeyUsage.Id, true,
-                //    new KeyUsage(KeyUsage.KeyCertSign));
+                foreach (var data in extensionDatas)
+                {
+                    certGenerator.AddExtension(data.OID, data.Critical, data.ExtensionValue);
+                }
             }
 
+            //if (isCertificateAuthority)
+            //{
+            //    certGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true,
+            //        new BasicConstraints(0));
+            //    certGenerator.AddExtension(X509Extensions.KeyUsage.Id, true,
+            //        new KeyUsage(KeyUsage.KeyCertSign));
+            //}
+
             return certGenerator.Generate(signatureFactory);
         }
 
@@ -153,21 +164,78 @@ namespace CAUtilLib
             }
         }
 
-        public static X509Certificate GenerateSelfSignedCertificate(AsymmetricCipherKeyPair kp, string commonName = "Zerova")
+        public static X509Certificate GenerateSelfSignedRootCertificate(
+            X509Name subject,
+            AsymmetricCipherKeyPair kp
+            )
         {
-            //var certName = new X509Name("CN=" + commomName);
-            var certName = CreateX509Name(commonName: commonName);
-            return GenerateCertificate(certName, certName, kp, kp.Public, isCertificateAuthority: true);
+            List<AddExtensionData> datas = new List<AddExtensionData>() { 
+                new AddExtensionData(){
+                    OID = X509Extensions.BasicConstraints.Id,
+                    Critical = true,
+                    ExtensionValue = new BasicConstraints(true)
+                },
+                new AddExtensionData()
+                {
+                    OID= X509Extensions.KeyUsage.Id,
+                    Critical = true,
+                    ExtensionValue = new KeyUsage(KeyUsage.DigitalSignature | KeyUsage.KeyCertSign | KeyUsage.CrlSign)
+                }
+            };
+            return GenerateCertificate(subject, subject, kp, kp.Public, extensionDatas: datas);
+        }
+
+        public static X509Certificate GenerateIntermediateCertificate(
+            Pkcs10CertificationRequest csr,
+            X509Certificate rca,
+            AsymmetricCipherKeyPair issuerKey,
+            int pathLengthConstraint
+            )
+        {
+            var csrInfo = csr.GetCertificationRequestInfo();
+
+            List<AddExtensionData> datas = new List<AddExtensionData>() {
+                new AddExtensionData(){
+                    OID = X509Extensions.BasicConstraints.Id,
+                    Critical = true,
+                    ExtensionValue = new BasicConstraints(pathLengthConstraint)
+                },
+                new AddExtensionData()
+                {
+                    OID= X509Extensions.KeyUsage.Id,
+                    Critical = true,
+                    ExtensionValue = new KeyUsage(KeyUsage.DigitalSignature | KeyUsage.KeyCertSign | KeyUsage.CrlSign)
+                }
+            };
+            return GenerateCertificate(rca.SubjectDN, csrInfo.Subject, issuerKey, csr.GetPublicKey(), extensionDatas: datas);
+        }
+
+        public static X509Certificate GenerateEndCertificate(
+            Pkcs10CertificationRequest csr,
+            X509Certificate rca,
+            AsymmetricCipherKeyPair issuerKey
+            )
+        {
+            var csrInfo = csr.GetCertificationRequestInfo();
+
+            List<AddExtensionData> datas = new List<AddExtensionData>() {
+                new AddExtensionData()
+                {
+                    OID= X509Extensions.KeyUsage.Id,
+                    Critical = true,
+                    ExtensionValue = new KeyUsage(KeyUsage.DigitalSignature | KeyUsage.NonRepudiation | KeyUsage.KeyEncipherment)
+                }
+            };
+            return GenerateCertificate(rca.SubjectDN, csrInfo.Subject, issuerKey, csr.GetPublicKey(), extensionDatas: datas);
         }
 
         public static X509Certificate SignCertificate(
             Pkcs10CertificationRequest csr,
             X509Certificate rca, 
-            AsymmetricCipherKeyPair issuerKey,
-            bool isCertificateAuthority = false)
+            AsymmetricCipherKeyPair issuerKey)
         {
             var csrInfo = csr.GetCertificationRequestInfo();
-            return GenerateCertificate(rca.SubjectDN, csrInfo.Subject, issuerKey, csr.GetPublicKey(), issuerSerialNumber: rca.SerialNumber, isCertificateAuthority: isCertificateAuthority);
+            return GenerateCertificate(rca.SubjectDN, csrInfo.Subject, issuerKey, csr.GetPublicKey(), issuerSerialNumber: rca.SerialNumber);
         }
 
         public static Pkcs10CertificationRequest CreateCertificateReq(AsymmetricCipherKeyPair kp, string commonName, string organizationName)
@@ -175,7 +243,7 @@ namespace CAUtilLib
             var subject = CreateX509Name(commonName: commonName, organizationName: organizationName);
 
             var csr = new Pkcs10CertificationRequest(
-                PkcsObjectIdentifiers.Sha512WithRsaEncryption.ToString(),
+                PkcsObjectIdentifiers.Sha256WithRsaEncryption.ToString(),
                 subject,
                 kp.Public,
                 null,

+ 2 - 1
CAUtilLib/CAUtil.cs

@@ -31,7 +31,8 @@ namespace CAUtilLib
                 return false;
             }
 
-            X509Certificate cert = BouncyCastleWrapper.GenerateSelfSignedCertificate(kp);
+            var subject = BouncyCastleWrapper.CreateX509Name(commonName: "Zerova");
+            X509Certificate cert = BouncyCastleWrapper.GenerateSelfSignedRootCertificate(subject, kp);
             var saveCertResult = await BouncyCastleWrapper.TrySaveAsPemAsync(RcaCertPath, new object[] { cert, kp.Private });
             if (!saveCertResult)
             {

+ 11 - 2
CertificateAutorityServer/Controllers/RootController.cs

@@ -34,7 +34,8 @@ namespace CertificateAutorityServer.Controllers
             {
                 return BadRequest("key parse failed");
             }
-            var cert = BouncyCastleWrapper.GenerateCertificate(subject, subject, key, key.Public , isCertificateAuthority: true);
+            //var cert = BouncyCastleWrapper.GenerateCertificate(subject, subject, key, key.Public);
+            var cert = BouncyCastleWrapper.GenerateSelfSignedRootCertificate(subject, key);
             if (cert is null)
             {
                 return BadRequest("certificate create failed");
@@ -56,7 +57,15 @@ namespace CertificateAutorityServer.Controllers
             var csr = BouncyCastleWrapper.LoadPemCsrFromString(signCsrReq.Csr);
             var rca = BouncyCastleWrapper.LoadPemCertFromString(signCsrReq.Rca);
             var key = BouncyCastleWrapper.LoadPemKeyFromString(signCsrReq.RcaKey);
-            var crt = BouncyCastleWrapper.SignCertificate(csr, rca, key , isCertificateAuthority: signCsrReq.IsCa);
+            Org.BouncyCastle.X509.X509Certificate crt;
+            if (signCsrReq.IsCa)
+            {
+                crt = BouncyCastleWrapper.GenerateIntermediateCertificate(csr, rca, key, 0);
+            }
+            else
+            {
+                crt = BouncyCastleWrapper.GenerateEndCertificate(csr, rca, key);
+            }
             var crtString = await BouncyCastleWrapper.ToStringAsPem(crt);
             return Ok(crtString);
         }

+ 6 - 3
CertificateAutorityServer/Service/CertificateService.cs

@@ -47,14 +47,16 @@ namespace CertificateAutorityServer.Service
             {
                 AsymmetricCipherKeyPair kp = BouncyCastleWrapper.GenerateRsaKeyPair(4096);
                 var saveKeyResult = BouncyCastleWrapper.TrySaveAsPemAsync(RcaKeyPath, new object[] { kp.Private }).Result;
-                X509Certificate cert = BouncyCastleWrapper.GenerateSelfSignedCertificate(kp);
+                var subject = BouncyCastleWrapper.CreateX509Name(commonName: "Zerova");
+                X509Certificate cert = BouncyCastleWrapper.GenerateSelfSignedRootCertificate(subject, kp);
                 var saveCertResult = BouncyCastleWrapper.TrySaveAsPemAsync(RcaCertPath, new object[] { cert, kp.Private }).Result;
                 return;
             }
             if (!File.Exists(RcaCertPath))
             {
                 var kp = BouncyCastleWrapper.LoadPemKeyFromFile(RcaKeyPath).Result;
-                var cert = BouncyCastleWrapper.GenerateSelfSignedCertificate(kp, config.DefaultRcaConfig.CommonName);
+                var subject = BouncyCastleWrapper.CreateX509Name(commonName: config.DefaultRcaConfig.CommonName);
+                var cert = BouncyCastleWrapper.GenerateSelfSignedRootCertificate(subject, kp);
                 var saveCertResult = BouncyCastleWrapper.TrySaveAsPemAsync(RcaCertPath, new object[] { cert, kp.Private }).Result;
             }
         }
@@ -83,7 +85,8 @@ namespace CertificateAutorityServer.Service
             var cert = await BouncyCastleWrapper.LoadPemCertFromFile(RcaKeyPath);
             var rcaKey = await BouncyCastleWrapper.LoadPemKeyFromFile(RcaKeyPath);
             var csr = BouncyCastleWrapper.LoadPemCsrFromString(signCsrReq.Csr);
-            var singedCert = BouncyCastleWrapper.SignCertificate(csr, cert, rcaKey);
+            //var singedCert = BouncyCastleWrapper.SignCertificate(csr, cert, rcaKey);
+            var singedCert = BouncyCastleWrapper.GenerateEndCertificate(csr, cert, rcaKey);
             return await BouncyCastleWrapper.ToStringAsPem(singedCert);
         }