public void Constructor_ASN1()
        {
            BasicConstraintsExtension ext = new BasicConstraintsExtension();
            BasicConstraintsExtension bce = new BasicConstraintsExtension(ext.ASN1);

            Empty(bce);
        }
Ejemplo n.º 2
0
        private bool IsParent(X509Certificate child, X509Certificate parent)
        {
            if (child.IssuerName != parent.SubjectName)
            {
                return(false);
            }

            // parent MUST have the Basic Constraint CA=true (except for trusted roots)
            // see why at http://www.microsoft.com/technet/security/bulletin/MS02-050.asp
            if ((parent.Version > 2) && (!IsTrusted(parent)))
            {
                // TODO: we do not support pathLenConstraint
                X509Extension ext = parent.Extensions ["2.5.29.19"];
                if (ext != null)
                {
                    BasicConstraintsExtension bc = new BasicConstraintsExtension(ext);
                    if (!bc.CertificateAuthority)
                    {
                        _status = X509ChainStatusFlags.InvalidBasicConstraints;
                    }
                }
                else
                {
                    _status = X509ChainStatusFlags.InvalidBasicConstraints;
                }
            }

            if (!child.VerifySignature(parent.RSA))
            {
                _status = X509ChainStatusFlags.NotSignatureValid;
                return(false);
            }
            return(true);
        }
Ejemplo n.º 3
0
 private bool IsParent(X509Certificate child, X509Certificate parent)
 {
     if (child.IssuerName != parent.SubjectName)
     {
         return(false);
     }
     if (parent.Version > 2 && !this.IsTrusted(parent))
     {
         X509Extension x509Extension = parent.Extensions["2.5.29.19"];
         if (x509Extension != null)
         {
             BasicConstraintsExtension basicConstraintsExtension = new BasicConstraintsExtension(x509Extension);
             if (!basicConstraintsExtension.CertificateAuthority)
             {
                 this._status = X509ChainStatusFlags.InvalidBasicConstraints;
             }
         }
         else
         {
             this._status = X509ChainStatusFlags.InvalidBasicConstraints;
         }
     }
     if (!child.VerifySignature(parent.RSA))
     {
         this._status = X509ChainStatusFlags.NotSignatureValid;
         return(false);
     }
     return(true);
 }
 private void Empty(BasicConstraintsExtension bce)
 {
     Assert.IsFalse(bce.Critical, "Critical");
     Assert.AreEqual("2.5.29.19", bce.Oid, "Oid");
     Assert.IsNotNull(bce.Name, "Name");
     Assert.IsFalse(bce.Name == bce.Oid, "Name!=Oid");
     Assert.IsFalse(bce.CertificateAuthority, "CertificateAuthority");
     Assert.AreEqual(BasicConstraintsExtension.NoPathLengthConstraint, bce.PathLenConstraint, "PathLenConstraint");
 }
Ejemplo n.º 5
0
        public bool VerifySignature(X509Certificate x509)
        {
            if (x509 == null)
            {
                throw new ArgumentNullException("x509");
            }
            if (x509.Version >= 3)
            {
                X509Extension x509Extension = x509.Extensions["2.5.29.15"];
                if (x509Extension != null)
                {
                    KeyUsageExtension keyUsageExtension = new KeyUsageExtension(x509Extension);
                    if (!keyUsageExtension.Support(KeyUsages.cRLSign))
                    {
                        return(false);
                    }
                }
                x509Extension = x509.Extensions["2.5.29.19"];
                if (x509Extension != null)
                {
                    BasicConstraintsExtension basicConstraintsExtension = new BasicConstraintsExtension(x509Extension);
                    if (!basicConstraintsExtension.CertificateAuthority)
                    {
                        return(false);
                    }
                }
            }
            if (this.issuer != x509.SubjectName)
            {
                return(false);
            }
            string text = this.signatureOID;

            if (text != null)
            {
                if (X509Crl.< > f__switch$map11 == null)
                {
                    X509Crl.< > f__switch$map11 = new Dictionary <string, int>(1)
                    {
                        {
                            "1.2.840.10040.4.3",
                            0
                        }
                    };
                }
                int num;
                if (X509Crl.< > f__switch$map11.TryGetValue(text, out num))
                {
                    if (num == 0)
                    {
                        return(this.VerifySignature(x509.DSA));
                    }
                }
            }
            return(this.VerifySignature(x509.RSA));
        }
Ejemplo n.º 6
0
        public bool VerifySignature(X509Certificate x509)
        {
            if (x509 == null)
            {
                throw new ArgumentNullException("x509");
            }
            if (x509.Version >= 3)
            {
                X509Extension extension = x509.Extensions["2.5.29.15"];
                if (extension != null)
                {
                    KeyUsageExtension extension2 = new KeyUsageExtension(extension);
                    if (!extension2.Support(KeyUsages.cRLSign))
                    {
                        return(false);
                    }
                }
                extension = x509.Extensions["2.5.29.19"];
                if (extension != null)
                {
                    BasicConstraintsExtension extension3 = new BasicConstraintsExtension(extension);
                    if (!extension3.CertificateAuthority)
                    {
                        return(false);
                    }
                }
            }
            if (this.issuer != x509.SubjectName)
            {
                return(false);
            }
            string signatureOID = this.signatureOID;

            if (signatureOID != null)
            {
                if (__f__switch_map12 == null)
                {
                    Dictionary <string, int> dictionary = new Dictionary <string, int>(1)
                    {
                        {
                            "1.2.840.10040.4.3",
                            0
                        }
                    };
                    __f__switch_map12 = dictionary;
                }
                if (__f__switch_map12.TryGetValue(signatureOID, out int num) && (num == 0))
                {
                    return(this.VerifySignature(x509.DSA));
                }
            }
            return(this.VerifySignature(x509.RSA));
        }
Ejemplo n.º 7
0
        public bool VerifySignature(X509Certificate x509)
        {
            if (x509 == null)
            {
                throw new ArgumentNullException("x509");
            }

            // 1. x509 certificate must be a CA certificate (unknown for v1 or v2 certs)
            if (x509.Version >= 3)
            {
                BasicConstraintsExtension basicConstraints = null;
                // 1.2. Check for ca = true in BasicConstraint
                X509Extension ext = x509.Extensions ["2.5.29.19"];
                if (ext != null)
                {
                    basicConstraints = new BasicConstraintsExtension(ext);
                    if (!basicConstraints.CertificateAuthority)
                    {
                        return(false);
                    }
                }
                // 1.1. Check for "cRLSign" bit in KeyUsage extension
                ext = x509.Extensions ["2.5.29.15"];
                if (ext != null)
                {
                    KeyUsageExtension keyUsage = new KeyUsageExtension(ext);
                    if (!keyUsage.Support(KeyUsages.cRLSign))
                    {
                        // 2nd chance if basicConstraints is CertificateAuthority
                        // and KeyUsage support digitalSignature
                        if ((basicConstraints == null) || !keyUsage.Support(KeyUsages.digitalSignature))
                        {
                            return(false);
                        }
                    }
                }
            }
            // 2. CRL issuer must match CA subject name
            if (issuer != x509.SubjectName)
            {
                return(false);
            }
            // 3. Check the CRL signature with the CA certificate public key
            switch (signatureOID)
            {
            case "1.2.840.10040.4.3":
                return(VerifySignature(x509.DSA));

            default:
                return(VerifySignature(x509.RSA));
            }
        }
        public void CertificateAuthority_NoPathLengthConstraint()
        {
            BasicConstraintsExtension bce = new BasicConstraintsExtension();

            bce.CertificateAuthority = true;
            bce.PathLenConstraint    = BasicConstraintsExtension.NoPathLengthConstraint;
            Assert.AreEqual("30-0C-06-03-55-1D-13-04-05-30-03-01-01-FF", BitConverter.ToString(bce.GetBytes()), "GetBytes");

            BasicConstraintsExtension bce2 = new BasicConstraintsExtension(bce.ASN1);

            Assert.IsFalse(bce2.Critical, "Critical");
            Assert.IsTrue(bce2.CertificateAuthority, "CertificateAuthority");
            Assert.AreEqual(BasicConstraintsExtension.NoPathLengthConstraint, bce2.PathLenConstraint, "PathLenConstraint");
        }
        public void CertificateAuthority_Critical()
        {
            BasicConstraintsExtension bce = new BasicConstraintsExtension();

            bce.Critical             = true;
            bce.CertificateAuthority = true;
            bce.PathLenConstraint    = 0;
            Assert.AreEqual("30-12-06-03-55-1D-13-01-01-FF-04-08-30-06-01-01-FF-02-01-00", BitConverter.ToString(bce.GetBytes()), "GetBytes");

            BasicConstraintsExtension bce2 = new BasicConstraintsExtension(bce.ASN1);

            Assert.IsTrue(bce2.Critical, "Critical");
            Assert.IsTrue(bce2.CertificateAuthority, "CertificateAuthority");
            Assert.AreEqual(0, bce2.PathLenConstraint, "PathLenConstraint");
        }
        public void NotCertificateAuthority()
        {
            BasicConstraintsExtension bce = new BasicConstraintsExtension();

            bce.CertificateAuthority = false;
            // CertificateAuthority isn't encoded (default value is false)
            bce.PathLenConstraint = Int32.MaxValue;
            // PathLenConstraint is ignored (per RFC3280)
            Assert.AreEqual("30-09-06-03-55-1D-13-04-02-30-00", BitConverter.ToString(bce.GetBytes()), "GetBytes");

            BasicConstraintsExtension bce2 = new BasicConstraintsExtension(bce.ASN1);

            Assert.IsFalse(bce2.Critical, "Critical");
            Assert.IsFalse(bce2.CertificateAuthority, "CertificateAuthority");
            Assert.AreEqual(BasicConstraintsExtension.NoPathLengthConstraint, bce2.PathLenConstraint, "PathLenConstraint");
        }
Ejemplo n.º 11
0
        private MSX509.X509Certificate2 GetRootCertificate()
        {
            List <X509Extension> extensions = new List <X509Extension>();

            BasicConstraintsExtension constraints = new BasicConstraintsExtension();

            constraints.CertificateAuthority = true;
            constraints.Critical             = true;
            extensions.Add(constraints);

            KeyUsageExtension keyUsage = new KeyUsageExtension();

            keyUsage.KeyUsage = KeyUsages.keyCertSign | KeyUsages.cRLSign;
            extensions.Add(keyUsage);

            return(CreateCertificate(state_.Config.X509.AuthorityName, extensions, null, state_.Config.X509.AuthorityName, MSX509.StoreName.Root, state_.Config.X509.RootValidity));
        }
Ejemplo n.º 12
0
        public bool VerifySignature(X509Certificate x509)
        {
            if (x509 == null)
            {
                throw new ArgumentNullException("x509");
            }
            if (x509.Version >= 3)
            {
                X509Extension x509Extension = x509.Extensions["2.5.29.15"];
                if (x509Extension != null)
                {
                    KeyUsageExtension keyUsageExtension = new KeyUsageExtension(x509Extension);
                    if (!keyUsageExtension.Support(KeyUsages.cRLSign))
                    {
                        return(false);
                    }
                }
                x509Extension = x509.Extensions["2.5.29.19"];
                if (x509Extension != null)
                {
                    BasicConstraintsExtension basicConstraintsExtension = new BasicConstraintsExtension(x509Extension);
                    if (!basicConstraintsExtension.CertificateAuthority)
                    {
                        return(false);
                    }
                }
            }
            if (issuer != x509.SubjectName)
            {
                return(false);
            }
            switch (signatureOID)
            {
            case "1.2.840.10040.4.3":
                return(VerifySignature(x509.DSA));

            default:
                return(VerifySignature(x509.RSA));
            }
        }
Ejemplo n.º 13
0
        internal MSX509.X509Certificate2 GetCertificate(string name)
        {
            List <X509Extension> extensions = new List <X509Extension>();

            BasicConstraintsExtension constraints = new BasicConstraintsExtension();

            constraints.CertificateAuthority = false;
            constraints.Critical             = true;
            extensions.Add(constraints);

            KeyUsageExtension keyUsage = new KeyUsageExtension();

            keyUsage.KeyUsage = KeyUsages.digitalSignature | KeyUsages.nonRepudiation | KeyUsages.keyEncipherment;
            extensions.Add(keyUsage);

            ExtendedKeyUsageExtension extendedUsage = new ExtendedKeyUsageExtension();

            extendedUsage.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
            extendedUsage.KeyPurpose.Add("1.3.6.1.5.5.7.3.2");
            extensions.Add(extendedUsage);

            return(CreateCertificate(name, extensions, GetRootCertificate(), state_.Config.X509.AuthorityName, MSX509.StoreName.My, state_.Config.X509.RootValidity));
        }
Ejemplo n.º 14
0
        public SelfCertificateDialog(IServiceProvider serviceProvider, CertificatesFeature feature)
            : base(serviceProvider)
        {
            InitializeComponent();
            cbStore.SelectedIndex   = 0;
            cbLength.SelectedIndex  = 3;
            cbHashing.SelectedIndex = 1;
            txtCommonName.Text      = Environment.MachineName;
            dtpFrom.Value           = DateTime.Now;
            dtpTo.Value             = dtpFrom.Value.AddYears(1);

            if (Environment.OSVersion.Version < Version.Parse("6.2"))
            {
                // IMPORTANT: WebHosting store is available since Windows 8.
                cbStore.Enabled = false;
            }

            if (!Helper.IsRunningOnMono())
            {
                NativeMethods.TryAddShieldToButton(btnOK);
            }

            var container = new CompositeDisposable();

            FormClosed += (sender, args) => container.Dispose();

            container.Add(
                Observable.FromEventPattern <EventArgs>(txtName, "TextChanged")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                btnOK.Enabled = !string.IsNullOrWhiteSpace(txtName.Text);
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnOK, "Click")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(evt =>
            {
                var names = txtCommonName.Text;
                if (string.IsNullOrWhiteSpace(names))
                {
                    ShowMessage("DNS names cannot be empty.", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                    return;
                }

                var dnsNames = names.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(item => item.Trim()).ToArray();
                if (dnsNames.Length == 0)
                {
                    ShowMessage("DNS names cannot be empty.", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                    return;
                }

                // Generate certificate
                string defaultIssuer  = string.Format("CN={0}", dnsNames[0]);
                string defaultSubject = defaultIssuer;
                byte[] sn             = Guid.NewGuid().ToByteArray();
                string subject        = defaultSubject;
                string issuer         = defaultIssuer;
                DateTime notBefore    = dtpFrom.Value;
                DateTime notAfter     = dtpTo.Value;

                RSA issuerKey  = new RSACryptoServiceProvider(int.Parse(cbLength.Text));
                RSA subjectKey = null;

                CspParameters subjectParams   = new CspParameters();
                CspParameters issuerParams    = new CspParameters();
                BasicConstraintsExtension bce = new BasicConstraintsExtension
                {
                    PathLenConstraint    = BasicConstraintsExtension.NoPathLengthConstraint,
                    CertificateAuthority = true
                };
                ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension();
                eku.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
                SubjectAltNameExtension alt = null;
                string p12File = Path.GetTempFileName();
                string p12pwd  = "test";

                // serial number MUST be positive
                if ((sn[0] & 0x80) == 0x80)
                {
                    sn[0] -= 0x80;
                }

                if (subject != defaultSubject)
                {
                    issuer    = subject;
                    issuerKey = null;
                }
                else
                {
                    subject    = issuer;
                    subjectKey = issuerKey;
                }

                if (subject == null)
                {
                    throw new Exception("Missing Subject Name");
                }

                X509CertificateBuilder cb = new X509CertificateBuilder(3);
                cb.SerialNumber           = sn;
                cb.IssuerName             = issuer;
                cb.NotBefore        = notBefore;
                cb.NotAfter         = notAfter;
                cb.SubjectName      = subject;
                cb.SubjectPublicKey = subjectKey;
                // extensions
                if (bce != null)
                {
                    cb.Extensions.Add(bce);
                }
                if (eku != null)
                {
                    cb.Extensions.Add(eku);
                }
                if (alt != null)
                {
                    cb.Extensions.Add(alt);
                }

                IDigest digest = new Sha1Digest();
                byte[] resBuf  = new byte[digest.GetDigestSize()];
                var spki       = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(DotNetUtilities.GetRsaPublicKey(issuerKey));
                byte[] bytes   = spki.PublicKeyData.GetBytes();
                digest.BlockUpdate(bytes, 0, bytes.Length);
                digest.DoFinal(resBuf, 0);

                cb.Extensions.Add(new SubjectKeyIdentifierExtension {
                    Identifier = resBuf
                });
                cb.Extensions.Add(new AuthorityKeyIdentifierExtension {
                    Identifier = resBuf
                });
                if (cbGenerate.Checked)
                {
                    SubjectAltNameExtension subjectAltNameExtension = new SubjectAltNameExtension(
                        new string[0],
                        dnsNames,
                        new string[0],
                        new string[0])
                    {
                        Critical = false
                    };
                    cb.Extensions.Add(subjectAltNameExtension);
                }

                // signature
                string hashName = cbHashing.SelectedIndex == 0 ? "SHA1" : "SHA256";
                cb.Hash         = hashName;
                byte[] rawcert  = null;
                try
                {
                    rawcert = cb.Sign(issuerKey);
                }
                catch (Exception ex)
                {
                    RollbarLocator.RollbarInstance.Error(ex);
                    ShowError(ex, "Certificate generation error", false);
                    return;
                }

                PKCS12 p12   = new PKCS12();
                p12.Password = p12pwd;

                ArrayList list = new ArrayList();
                // we use a fixed array to avoid endianess issues
                // (in case some tools requires the ID to be 1).
                list.Add(new byte[] { 1, 0, 0, 0 });
                Hashtable attributes = new Hashtable(1);
                attributes.Add(PKCS9.localKeyId, list);

                p12.AddCertificate(new X509Certificate(rawcert), attributes);
                p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);
                p12.SaveToFile(p12File);

                Item = new X509Certificate2(p12File, p12pwd)
                {
                    FriendlyName = txtName.Text
                };
                Store = cbStore.SelectedIndex == 0 ? "Personal" : "WebHosting";

                try
                {
                    using (var process = new Process())
                    {
                        // add certificate
                        var start       = process.StartInfo;
                        start.Verb      = "runas";
                        start.FileName  = "cmd";
                        start.Arguments = string.Format("/c \"\"{4}\" /f:\"{0}\" /p:{1} /n:\"{2}\" /s:{3}\"",
                                                        p12File,
                                                        p12pwd,
                                                        txtName.Text,
                                                        cbStore.SelectedIndex == 0 ? "MY" : "WebHosting",
                                                        Path.Combine(Environment.CurrentDirectory, "certificateinstaller.exe"));
                        start.CreateNoWindow = true;
                        start.WindowStyle    = ProcessWindowStyle.Hidden;
                        process.Start();
                        process.WaitForExit();
                        File.Delete(p12File);
                        if (process.ExitCode == 0)
                        {
                            DialogResult = DialogResult.OK;
                        }
                        else
                        {
                            ShowMessage(process.ExitCode.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
                        }
                    }
                }
                catch (Win32Exception ex)
                {
                    // elevation is cancelled.
                    if (ex.NativeErrorCode != Microsoft.Web.Administration.NativeMethods.ErrorCancelled)
                    {
                        RollbarLocator.RollbarInstance.Error(ex, new Dictionary <string, object> {
                            { "native", ex.NativeErrorCode }
                        });
                        // throw;
                    }
                }
                catch (Exception ex)
                {
                    RollbarLocator.RollbarInstance.Error(ex);
                }
            }));

            container.Add(
                Observable.FromEventPattern <CancelEventArgs>(this, "HelpButtonClicked")
                .ObserveOn(System.Threading.SynchronizationContext.Current)
                .Subscribe(EnvironmentVariableTarget =>
            {
                feature.ShowHelp();
            }));
        }
Ejemplo n.º 15
0
        public static int MakeCertMain(string[] args)
        {
            if (args.Length < 1)
            {
                Header();
                Console.WriteLine("ERROR: Missing output filename {0}", Environment.NewLine);
                Help();
                return(-1);
            }

            string fileName = args [args.Length - 1];

            // default values
            byte[]   sn        = Guid.NewGuid().ToByteArray();
            string   subject   = defaultSubject;
            string   issuer    = defaultIssuer;
            DateTime notBefore = DateTime.Now;
            DateTime notAfter  = new DateTime(643445675990000000);             // 12/31/2039 23:59:59Z

            RSA issuerKey = (RSA)RSA.Create();

            issuerKey.FromXmlString(MonoTestRootAgency);
            RSA subjectKey = (RSA)RSA.Create();

            bool   selfSigned = false;
            string hashName   = "SHA1";

            CspParameters             subjectParams = new CspParameters();
            CspParameters             issuerParams  = new CspParameters();
            BasicConstraintsExtension bce           = null;
            ExtendedKeyUsageExtension eku           = null;
            SubjectAltNameExtension   alt           = null;
            string          p12file           = null;
            string          p12pwd            = null;
            X509Certificate issuerCertificate = null;

            Header();
            try {
                int i = 0;
                while (i < args.Length)
                {
                    switch (args [i++])
                    {
                    // Basic options
                    case "-#":
                        // Serial Number
                        sn = BitConverter.GetBytes(Convert.ToInt32(args [i++]));
                        break;

                    case "-n":
                        // Subject Distinguish Name
                        subject = args [i++];
                        break;

                    case "-$":
                        // (authenticode) commercial or individual
                        // CRITICAL KeyUsageRestriction extension
                        // hash algorithm
                        string usageRestriction = args [i++].ToLower();
                        switch (usageRestriction)
                        {
                        case "commercial":
                        case "individual":
                            Console.WriteLine("WARNING: Unsupported deprecated certification extension KeyUsageRestriction not included");
//									Console.WriteLine ("WARNING: ExtendedKeyUsage for codesigning has been included.");
                            break;

                        default:
                            Console.WriteLine("Unsupported restriction " + usageRestriction);
                            return(-1);
                        }
                        break;

                    // Extended Options
                    case "-a":
                        // hash algorithm
                        switch (args [i++].ToLower())
                        {
                        case "sha1":
                            hashName = "SHA1";
                            break;

                        case "md5":
                            Console.WriteLine("WARNING: MD5 is no more safe for this usage.");
                            hashName = "MD5";
                            break;

                        default:
                            Console.WriteLine("Unsupported hash algorithm");
                            break;
                        }
                        break;

                    case "-b":
                        // Validity / notBefore
                        notBefore = DateTime.Parse(args [i++] + " 23:59:59", CultureInfo.InvariantCulture);
                        break;

                    case "-cy":
                        // basic constraints - autority or end-entity
                        switch (args [i++].ToLower())
                        {
                        case "authority":
                            if (bce == null)
                            {
                                bce = new BasicConstraintsExtension();
                            }
                            bce.CertificateAuthority = true;
                            break;

                        case "end":
                            // do not include extension
                            bce = null;
                            break;

                        case "both":
                            Console.WriteLine("ERROR: No more supported in X.509");
                            return(-1);

                        default:
                            Console.WriteLine("Unsupported certificate type");
                            return(-1);
                        }
                        break;

                    case "-d":
                        // CN private extension ?
                        Console.WriteLine("Unsupported option");
                        break;

                    case "-e":
                        // Validity / notAfter
                        notAfter = DateTime.Parse(args [i++] + " 23:59:59", CultureInfo.InvariantCulture);
                        break;

                    case "-eku":
                        // extendedKeyUsage extension
                        char[]   sep      = { ',' };
                        string[] purposes = args [i++].Split(sep);
                        if (eku == null)
                        {
                            eku = new ExtendedKeyUsageExtension();
                        }
                        foreach (string purpose in purposes)
                        {
                            eku.KeyPurpose.Add(purpose);
                        }
                        break;

                    case "-h":
                        // pathLength (basicConstraints)
                        // MS use an old basicConstrains (2.5.29.10) which
                        // allows both CA and End-Entity. This is no
                        // more supported with 2.5.29.19.
                        if (bce == null)
                        {
                            bce = new BasicConstraintsExtension();
                            bce.CertificateAuthority = true;
                        }
                        bce.PathLenConstraint = Convert.ToInt32(args [i++]);
                        break;

                    case "-alt":
                        if (alt == null)
                        {
                            string [] dnsNames = File.ReadAllLines(args [i++]);
                            alt = new SubjectAltNameExtension(null, dnsNames, null, null);
                        }
                        break;

                    case "-ic":
                        issuerCertificate = LoadCertificate(args [i++]);
                        issuer            = issuerCertificate.SubjectName;
                        break;

                    case "-in":
                        issuer = args [i++];
                        break;

                    case "-iv":
                        // TODO password
                        PrivateKey pvk = PrivateKey.CreateFromFile(args [i++]);
                        issuerKey = pvk.RSA;
                        break;

                    case "-l":
                        // link (URL)
                        // spcSpAgencyInfo private extension
                        Console.WriteLine("Unsupported option");
                        break;

                    case "-m":
                        // validity period (in months)
                        notAfter = notBefore.AddMonths(Convert.ToInt32(args [i++]));
                        break;

                    case "-nscp":
                        // Netscape's private extensions - NetscapeCertType
                        // BasicContraints - End Entity
                        Console.WriteLine("Unsupported option");
                        break;

                    case "-r":
                        selfSigned = true;
                        break;

                    case "-sc":
                        // subject certificate ? renew ?
                        Console.WriteLine("Unsupported option");
                        break;

                    // Issuer CspParameters options
                    case "-ik":
                        issuerParams.KeyContainerName = args [i++];
                        break;

                    case "-iky":
                        // select a key in the provider
                        string ikn = args [i++].ToLower();
                        switch (ikn)
                        {
                        case "signature":
                            issuerParams.KeyNumber = 0;
                            break;

                        case "exchange":
                            issuerParams.KeyNumber = 1;
                            break;

                        default:
                            issuerParams.KeyNumber = Convert.ToInt32(ikn);
                            break;
                        }
                        break;

                    case "-ip":
                        issuerParams.ProviderName = args [i++];
                        break;

                    case "-ir":
                        switch (args [i++].ToLower())
                        {
                        case "localmachine":
                            issuerParams.Flags = CspProviderFlags.UseMachineKeyStore;
                            break;

                        case "currentuser":
                            issuerParams.Flags = CspProviderFlags.UseDefaultKeyContainer;
                            break;

                        default:
                            Console.WriteLine("Unknown key store for issuer");
                            return(-1);
                        }
                        break;

                    case "-is":
                        Console.WriteLine("Unsupported option");
                        return(-1);

                    case "-iy":
                        issuerParams.ProviderType = Convert.ToInt32(args [i++]);
                        break;

                    // Subject CspParameters Options
                    case "-sk":
                        subjectParams.KeyContainerName = args [i++];
                        break;

                    case "-sky":
                        // select a key in the provider
                        string skn = args [i++].ToLower();
                        switch (skn)
                        {
                        case "signature":
                            subjectParams.KeyNumber = 0;
                            break;

                        case "exchange":
                            subjectParams.KeyNumber = 1;
                            break;

                        default:
                            subjectParams.KeyNumber = Convert.ToInt32(skn);
                            break;
                        }
                        break;

                    case "-sp":
                        subjectParams.ProviderName = args [i++];
                        break;

                    case "-sr":
                        switch (args [i++].ToLower())
                        {
                        case "localmachine":
                            subjectParams.Flags = CspProviderFlags.UseMachineKeyStore;
                            break;

                        case "currentuser":
                            subjectParams.Flags = CspProviderFlags.UseDefaultKeyContainer;
                            break;

                        default:
                            Console.WriteLine("Unknown key store for subject");
                            return(-1);
                        }
                        break;

                    case "-ss":
                        Console.WriteLine("Unsupported option");
                        return(-1);

                    case "-sv":
                        string pvkFile = args [i++];
                        if (File.Exists(pvkFile))
                        {
                            PrivateKey key = PrivateKey.CreateFromFile(pvkFile);
                            subjectKey = key.RSA;
                        }
                        else
                        {
                            PrivateKey key = new PrivateKey();
                            key.RSA = subjectKey;
                            key.Save(pvkFile);
                        }
                        break;

                    case "-sy":
                        subjectParams.ProviderType = Convert.ToInt32(args [i++]);
                        break;

                    // Mono Specific Options
                    case "-p12":
                        p12file = args [i++];
                        p12pwd  = args [i++];
                        break;

                    // Other options
                    case "-?":
                        Help();
                        return(0);

                    case "-!":
                        ExtendedHelp();
                        return(0);

                    default:
                        if (i != args.Length)
                        {
                            Console.WriteLine("ERROR: Unknown parameter");
                            Help();
                            return(-1);
                        }
                        break;
                    }
                }

                // serial number MUST be positive
                if ((sn [0] & 0x80) == 0x80)
                {
                    sn [0] -= 0x80;
                }

                if (selfSigned)
                {
                    if (subject != defaultSubject)
                    {
                        issuer    = subject;
                        issuerKey = subjectKey;
                    }
                    else
                    {
                        subject    = issuer;
                        subjectKey = issuerKey;
                    }
                }

                if (subject == null)
                {
                    throw new Exception("Missing Subject Name");
                }

                X509CertificateBuilder cb = new X509CertificateBuilder(3);
                cb.SerialNumber     = sn;
                cb.IssuerName       = issuer;
                cb.NotBefore        = notBefore;
                cb.NotAfter         = notAfter;
                cb.SubjectName      = subject;
                cb.SubjectPublicKey = subjectKey;
                // extensions
                if (bce != null)
                {
                    cb.Extensions.Add(bce);
                }
                if (eku != null)
                {
                    cb.Extensions.Add(eku);
                }
                if (alt != null)
                {
                    cb.Extensions.Add(alt);
                }
                // signature
                cb.Hash = hashName;
                byte[] rawcert = cb.Sign(issuerKey);

                if (p12file == null)
                {
                    WriteCertificate(fileName, rawcert);
                }
                else
                {
                    PKCS12 p12 = new PKCS12();
                    p12.Password = p12pwd;

                    ArrayList list = new ArrayList();
                    // we use a fixed array to avoid endianess issues
                    // (in case some tools requires the ID to be 1).
                    list.Add(new byte [4] {
                        1, 0, 0, 0
                    });
                    Hashtable attributes = new Hashtable(1);
                    attributes.Add(PKCS9.localKeyId, list);

                    p12.AddCertificate(new X509Certificate(rawcert), attributes);
                    if (issuerCertificate != null)
                    {
                        p12.AddCertificate(issuerCertificate);
                    }
                    p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);
                    p12.SaveToFile(p12file);
                }
                return(0);
            }
            catch (Exception e) {
                Console.WriteLine("ERROR: " + e.ToString());
                Help();
            }
            return(1);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Applies the basic constrains and key usages to the underlying certificate builder
        /// before the certificate is signed.
        /// </summary>
        void PrepareSigning()
        {
            // Set the signing hashing function
            _builder.Hash = "SHA256";

            // Clear all extensions created during the previous preparation
            _builder.Extensions.Clear();

            #region Subject

            if (SubjectAlternativeNames != null && SubjectAlternativeNames.Count > 0)
            {
                var dnsNameList = new List <string>();
                var ipList      = new List <string>();

                foreach (var item in SubjectAlternativeNames)
                {
                    IPAddress ipAddress;
                    if (IPAddress.TryParse(item, out ipAddress))
                    {
                        ipList.Add(item);
                    }
                    else
                    {
                        dnsNameList.Add(item);
                    }
                }

                var extension = new SubjectAltNameExtension(null, dnsNameList.ToArray(), ipList.ToArray(), null);
                _builder.Extensions.Add(extension);
            }

            #endregion

            #region Serial number

            {
                var serialNumber = _serialNumber == null ? null : (byte[])_serialNumber.Clone();

                if (serialNumber == null)
                {
                    serialNumber = Guid.NewGuid().ToByteArray();
                }

                /* // The serial number is correctly set and must NOT be reversed
                 * // Convert the serial number to big endian format
                 * Array.Reverse(serialNumber);
                 */

                _builder.SerialNumber = serialNumber;
            }

            #endregion

            #region Basic key usages

            var keyUsages = KeyUsages;

            if (IsCertificateAuthority)
            {
                // Indicate that the public key of the certificate can be used to validate the signatures of
                // other certificates
                keyUsages |= BasicKeyUsages.KeyCertSign;

                var extension = new BasicConstraintsExtension()
                {
                    CertificateAuthority = true,
                    PathLenConstraint    = CertificateAuthorityPathLength,
                    // This extension must be critical
                    Critical = true,
                };

                _builder.Extensions.Add(extension);
            }
            else
            {
                keyUsages &= ~BasicKeyUsages.KeyCertSign;
            }

            if (keyUsages != BasicKeyUsages.None)
            {
#if MONO_BUG
                // There was a bug in the Mono implementation of the KeyUsageExtension
                // which is still NOT fixed
                var buffer = new System.Security.Cryptography.X509Certificates.X509KeyUsageExtension(
                    (System.Security.Cryptography.X509Certificates.X509KeyUsageFlags)keyUsages,
                    false
                    ).RawData;

                var asn = new ASN1(0x30, buffer);

                asn.Add(ASN1Convert.FromOid("2.5.29.15"));

                asn.Add(new ASN1(4, buffer));

                _builder.Extensions.Add(new X509Extension(asn)
                {
                    Critical = KeyUsagesCritical
                });
#else
                // This code should be used once the bug is fixed
                var extension = new KeyUsageExtension()
                {
                    KeyUsage = (KeyUsages)keyUsages,
                    Critical = KeyUsagesCritical,
                };

                _builder.Extensions.Add(extension);
#endif
            }

            #endregion

            #region Extended key usage

            if (ExtendedKeyUsages != null && ExtendedKeyUsages.Count > 0)
            {
                var extension = new ExtendedKeyUsageExtension();

                extension.Critical = ExtendedKeyUsagesCritical;

                foreach (var item in ExtendedKeyUsages)
                {
                    // Avoid dupliated key usages
                    if (false == extension.KeyPurpose.Contains(item))
                    {
                        extension.KeyPurpose.Add(item);
                    }
                }

                _builder.Extensions.Add(extension);
            }

            #endregion

            #region Custom extensions

            if (_extensions != null)
            {
                _builder.Extensions.AddRange(_extensions);
            }

            #endregion
        }
Ejemplo n.º 17
0
        static void Main(string[] args)
        {
            var assembly = Assembly.GetExecutingAssembly();
            var title    = (AssemblyTitleAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyTitleAttribute));

            Console.WriteLine("{0} version {1}", title.Title, assembly.GetName().Version);
            var copyright = (AssemblyCopyrightAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyCopyrightAttribute));

            Console.WriteLine(copyright.Copyright);
            Console.WriteLine("More information can be found at https://www.jexusmanager.com");
            Console.WriteLine();

            var baseAddress = args.Length > 0 ? args[0] : "https://*****:*****@"Remote services must be run as root on Linux.");
                    return;
                }

                if (!File.Exists("jws"))
                {
                    Console.WriteLine(@"Remote services must be running in Jexus installation folder.");
                    return;
                }

                var loc  = baseAddress.LastIndexOf(':');
                var port = "443";
                if (loc != -1)
                {
                    port = baseAddress.Substring(loc + 1);
                }

                string dirname = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                string path    = Path.Combine(dirname, ".mono", "httplistener");
                if (false == Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                string target_cert = Path.Combine(path, string.Format("{0}.cer", port));
                if (File.Exists(target_cert))
                {
                    Console.WriteLine("Use {0}", target_cert);
                }
                else
                {
                    Console.WriteLine("Generating a self-signed certificate for Jexus Manager");

                    // Generate certificate
                    string   defaultIssuer  = "CN=jexus.lextudio.com";
                    string   defaultSubject = "CN=jexus.lextudio.com";
                    byte[]   sn             = Guid.NewGuid().ToByteArray();
                    string   subject        = defaultSubject;
                    string   issuer         = defaultIssuer;
                    DateTime notBefore      = DateTime.Now;
                    DateTime notAfter       = new DateTime(643445675990000000); // 12/31/2039 23:59:59Z

                    RSA issuerKey  = new RSACryptoServiceProvider(2048);
                    RSA subjectKey = null;

                    bool   selfSigned = true;
                    string hashName   = "SHA1";

                    CspParameters             subjectParams = new CspParameters();
                    CspParameters             issuerParams  = new CspParameters();
                    BasicConstraintsExtension bce           = new BasicConstraintsExtension
                    {
                        PathLenConstraint    = BasicConstraintsExtension.NoPathLengthConstraint,
                        CertificateAuthority = true
                    };
                    ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension();
                    eku.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
                    SubjectAltNameExtension alt = null;
                    string p12file = Path.Combine(path, "temp.pfx");
                    string p12pwd  = "test";

                    // serial number MUST be positive
                    if ((sn[0] & 0x80) == 0x80)
                    {
                        sn[0] -= 0x80;
                    }

                    if (selfSigned)
                    {
                        if (subject != defaultSubject)
                        {
                            issuer    = subject;
                            issuerKey = subjectKey;
                        }
                        else
                        {
                            subject    = issuer;
                            subjectKey = issuerKey;
                        }
                    }

                    if (subject == null)
                    {
                        throw new Exception("Missing Subject Name");
                    }

                    X509CertificateBuilder cb = new X509CertificateBuilder(3);
                    cb.SerialNumber     = sn;
                    cb.IssuerName       = issuer;
                    cb.NotBefore        = notBefore;
                    cb.NotAfter         = notAfter;
                    cb.SubjectName      = subject;
                    cb.SubjectPublicKey = subjectKey;
                    // extensions
                    if (bce != null)
                    {
                        cb.Extensions.Add(bce);
                    }
                    if (eku != null)
                    {
                        cb.Extensions.Add(eku);
                    }
                    if (alt != null)
                    {
                        cb.Extensions.Add(alt);
                    }

                    IDigest digest = new Sha1Digest();
                    byte[]  resBuf = new byte[digest.GetDigestSize()];
                    var     spki   = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(DotNetUtilities.GetRsaPublicKey(issuerKey));
                    byte[]  bytes  = spki.PublicKeyData.GetBytes();
                    digest.BlockUpdate(bytes, 0, bytes.Length);
                    digest.DoFinal(resBuf, 0);

                    cb.Extensions.Add(new SubjectKeyIdentifierExtension {
                        Identifier = resBuf
                    });
                    cb.Extensions.Add(new AuthorityKeyIdentifierExtension {
                        Identifier = resBuf
                    });
                    // signature
                    cb.Hash = hashName;
                    byte[] rawcert = cb.Sign(issuerKey);

                    PKCS12 p12 = new PKCS12();
                    p12.Password = p12pwd;

                    ArrayList list = new ArrayList();
                    // we use a fixed array to avoid endianess issues
                    // (in case some tools requires the ID to be 1).
                    list.Add(new byte[4] {
                        1, 0, 0, 0
                    });
                    Hashtable attributes = new Hashtable(1);
                    attributes.Add(PKCS9.localKeyId, list);

                    p12.AddCertificate(new Mono.Security.X509.X509Certificate(rawcert), attributes);
                    p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);
                    p12.SaveToFile(p12file);

                    var x509 = new System.Security.Cryptography.X509Certificates.X509Certificate2(p12file, p12pwd, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable);

                    // Install certificate
                    string target_pvk = Path.Combine(path, string.Format("{0}.pvk", port));

                    using (Stream cer = File.OpenWrite(target_cert))
                    {
                        byte[] raw = x509.RawData;
                        cer.Write(raw, 0, raw.Length);
                    }

                    PrivateKey pvk = new PrivateKey();
                    pvk.RSA = subjectKey;
                    pvk.Save(target_pvk);
                }
            }

            JexusServer.Credentials = args.Length > 2 ? args[1] + "|" + args[2] : "jexus|lextudio.com";
            JexusServer.Timeout     = args.Length > 3 ? double.Parse(args[3]) : 30D;

            using (WebApp.Start <Startup>(url: baseAddress))
            {
                Console.WriteLine("Remote services have started at {0}.", baseAddress);
                Console.WriteLine("Credentials is {0}", JexusServer.Credentials);
                Console.WriteLine("Press Enter to quit.");
                Console.ReadLine();
            }
        }
Ejemplo n.º 18
0
        public SelfCertificateDialog(IServiceProvider serviceProvider)
            : base(serviceProvider)
        {
            InitializeComponent();
            cbStore.SelectedIndex   = 0;
            cbLength.SelectedIndex  = 3;
            cbHashing.SelectedIndex = 1;
            txtCommonName.Text      = Environment.MachineName;

            if (Environment.OSVersion.Version.Major < 8)
            {
                // IMPORTANT: WebHosting store is available since Windows 8.
                cbStore.Enabled = false;
            }

            if (!Helper.IsRunningOnMono())
            {
                NativeMethods.TryAddShieldToButton(btnOK);
            }

            var container = new CompositeDisposable();

            FormClosed += (sender, args) => container.Dispose();

            container.Add(
                Observable.FromEventPattern <EventArgs>(txtName, "TextChanged")
                .Subscribe(evt =>
            {
                btnOK.Enabled = !string.IsNullOrWhiteSpace(txtName.Text);
            }));

            container.Add(
                Observable.FromEventPattern <EventArgs>(btnOK, "Click")
                .Subscribe(evt =>
            {
                // Generate certificate
                string defaultIssuer  = string.Format("CN={0}", txtCommonName.Text);
                string defaultSubject = defaultIssuer;
                byte[] sn             = Guid.NewGuid().ToByteArray();
                string subject        = defaultSubject;
                string issuer         = defaultIssuer;
                DateTime notBefore    = DateTime.Now;
                DateTime notAfter     = new DateTime(643445675990000000); // 12/31/2039 23:59:59Z

                RSA issuerKey  = new RSACryptoServiceProvider(int.Parse(cbLength.Text));
                RSA subjectKey = null;

                CspParameters subjectParams   = new CspParameters();
                CspParameters issuerParams    = new CspParameters();
                BasicConstraintsExtension bce = new BasicConstraintsExtension
                {
                    PathLenConstraint    = BasicConstraintsExtension.NoPathLengthConstraint,
                    CertificateAuthority = true
                };
                ExtendedKeyUsageExtension eku = new ExtendedKeyUsageExtension();
                eku.KeyPurpose.Add("1.3.6.1.5.5.7.3.1");
                SubjectAltNameExtension alt = null;
                string p12File = Path.GetTempFileName();
                string p12pwd  = "test";

                // serial number MUST be positive
                if ((sn[0] & 0x80) == 0x80)
                {
                    sn[0] -= 0x80;
                }

                if (subject != defaultSubject)
                {
                    issuer    = subject;
                    issuerKey = null;
                }
                else
                {
                    subject    = issuer;
                    subjectKey = issuerKey;
                }

                if (subject == null)
                {
                    throw new Exception("Missing Subject Name");
                }

                X509CertificateBuilder cb = new X509CertificateBuilder(3);
                cb.SerialNumber           = sn;
                cb.IssuerName             = issuer;
                cb.NotBefore        = notBefore;
                cb.NotAfter         = notAfter;
                cb.SubjectName      = subject;
                cb.SubjectPublicKey = subjectKey;
                // extensions
                if (bce != null)
                {
                    cb.Extensions.Add(bce);
                }
                if (eku != null)
                {
                    cb.Extensions.Add(eku);
                }
                if (alt != null)
                {
                    cb.Extensions.Add(alt);
                }

                IDigest digest = new Sha1Digest();
                byte[] resBuf  = new byte[digest.GetDigestSize()];
                var spki       = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(DotNetUtilities.GetRsaPublicKey(issuerKey));
                byte[] bytes   = spki.PublicKeyData.GetBytes();
                digest.BlockUpdate(bytes, 0, bytes.Length);
                digest.DoFinal(resBuf, 0);

                cb.Extensions.Add(new SubjectKeyIdentifierExtension {
                    Identifier = resBuf
                });
                cb.Extensions.Add(new AuthorityKeyIdentifierExtension {
                    Identifier = resBuf
                });
                // signature
                string hashName = cbHashing.SelectedIndex == 0 ? "SHA1" : "SHA256";
                cb.Hash         = hashName;
                byte[] rawcert  = cb.Sign(issuerKey);

                PKCS12 p12   = new PKCS12();
                p12.Password = p12pwd;

                ArrayList list = new ArrayList();
                // we use a fixed array to avoid endianess issues
                // (in case some tools requires the ID to be 1).
                list.Add(new byte[] { 1, 0, 0, 0 });
                Hashtable attributes = new Hashtable(1);
                attributes.Add(PKCS9.localKeyId, list);

                p12.AddCertificate(new X509Certificate(rawcert), attributes);
                p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);
                p12.SaveToFile(p12File);

                Item = new X509Certificate2(p12File, p12pwd)
                {
                    FriendlyName = txtName.Text
                };
                Store = cbStore.SelectedIndex == 0 ? "Personal" : "WebHosting";

                try
                {
                    using (var process = new Process())
                    {
                        // add certificate
                        var start       = process.StartInfo;
                        start.Verb      = "runas";
                        start.FileName  = "cmd";
                        start.Arguments = string.Format("/c \"\"{4}\" /f:\"{0}\" /p:{1} /n:\"{2}\" /s:{3}\"",
                                                        p12File,
                                                        p12pwd,
                                                        txtName.Text,
                                                        cbStore.SelectedIndex == 0 ? "MY" : "WebHosting",
                                                        Path.Combine(Environment.CurrentDirectory, "certificateinstaller.exe"));
                        start.CreateNoWindow = true;
                        start.WindowStyle    = ProcessWindowStyle.Hidden;
                        process.Start();
                        process.WaitForExit();
                        File.Delete(p12File);
                        if (process.ExitCode == 0)
                        {
                            this.DialogResult = DialogResult.OK;
                        }
                        else
                        {
                            MessageBox.Show(process.ExitCode.ToString());
                        }
                    }
                }
                catch (Exception)
                {
                    // elevation is cancelled.
                }
            }));
        }
        public void Constructor_Empty()
        {
            BasicConstraintsExtension bce = new BasicConstraintsExtension();

            Empty(bce);
        }
        public void NegativePathLenConstraint()
        {
            BasicConstraintsExtension bce = new BasicConstraintsExtension();

            bce.PathLenConstraint = Int32.MinValue;
        }
Ejemplo n.º 21
0
        // TODO : cleanup and reorganization, as the code below is a almost a direct copypaste from Mono project's Makecert tool.
        internal /* byte[]*/ PKCS12 GenerateCertificate(/*string[] args,*/ bool isHubRootCA, bool isHubCert, string subjectName, string[] alternateDnsNames)
        {
            if (isHubRootCA && isHubCert)
            {
                throw new Exception("incompatible options isHubRootCA & isHubCert");
            }
            Logger.Append("HUBRN", Severity.INFO, "Asked to create " + ((isHubCert)?"hub certificate, ":"") + ((isHubRootCA)?"root CA, ":"") + ((!isHubCert && !isHubRootCA)?" node certificate for '" + subjectName + "'":""));
            string rootKey  = ConfigurationManager.AppSettings["Security.CAKey"];
            string rootCert = ConfigurationManager.AppSettings["Security.CACertificate"];

            byte[]   sn        = Guid.NewGuid().ToByteArray();
            string   issuer    = defaultIssuer;
            DateTime notBefore = DateTime.Now;
            DateTime notAfter  = DateTime.Now.AddYears(5);

            RSA issuerKey = (RSA)RSA.Create();
            //issuerKey.FromXmlString(MonoTestRootAgency);
            RSA subjectKey = (RSA)RSA.Create();

            bool   selfSigned = isHubRootCA;
            string hashName   = "SHA1";

            BasicConstraintsExtension bce     = null;
            ExtendedKeyUsageExtension eku     = null;
            SubjectAltNameExtension   alt     = null;
            string          p12pwd            = null;
            X509Certificate issuerCertificate = null;

            try{
                if (subjectName == null)
                {
                    throw new Exception("Missing Subject Name");
                }
                if (!subjectName.ToLower().StartsWith("cn="))
                {
                    subjectName = "CN=" + subjectName;
                }

                /*if (alternateDnsNames != null){
                 *      alt = new SubjectAltNameExtension(null, alternateDnsNames, null, null);
                 * }*/
                if (!isHubRootCA)
                {
                    issuerCertificate = LoadCertificate(rootCert);
                    issuer            = issuerCertificate.SubjectName;

                    //case "-iv":
                    // TODO password
                    PrivateKey pvk = PrivateKey.CreateFromFile(rootKey);
                    issuerKey = pvk.RSA;
                }

                // Issuer CspParameters options
                if (isHubRootCA)
                {
                    //subjectName = defaultSubject;
                    string pvkFile = rootKey;
                    if (File.Exists(pvkFile))                       // CA key already exists, reuse
                    {
                        PrivateKey key = PrivateKey.CreateFromFile(pvkFile);
                        subjectKey = key.RSA;
                    }
                    else
                    {
                        PrivateKey key = new PrivateKey();
                        key.RSA = subjectKey;
                        key.Save(pvkFile);
                        // save 'the Mother Of All Keys'
                        //WriteHubMotherCert(issuerKey.ToXmlString(true));
                    }
                }
                else
                {
                    p12pwd = "";
                }

                // serial number MUST be positive
                if ((sn [0] & 0x80) == 0x80)
                {
                    sn [0] -= 0x80;
                }

                if (selfSigned)
                {
                    if (subjectName != defaultSubject)
                    {
                        issuer    = subjectName;
                        issuerKey = subjectKey;
                        //issuerKey = Hub.MotherKey;
                    }
                    else
                    {
                        subjectName = issuer;
                        subjectKey  = issuerKey;
                    }
                }

                X509CertificateBuilder cb = new X509CertificateBuilder(3);
                cb.SerialNumber     = sn;
                cb.IssuerName       = issuer;
                cb.NotBefore        = notBefore;
                cb.NotAfter         = notAfter;
                cb.SubjectName      = subjectName;
                cb.SubjectPublicKey = subjectKey;

                // extensions
                if (bce != null)
                {
                    cb.Extensions.Add(bce);
                }
                if (eku != null)
                {
                    cb.Extensions.Add(eku);
                }
                if (alt != null)
                {
                    cb.Extensions.Add(alt);
                }
                // signature
                cb.Hash = hashName;
                byte[] rawcert = cb.Sign(issuerKey);

                if (isHubRootCA)                 // Hub CA
                {
                    WriteCACertificate(rawcert);
                }
                else
                {
                    PKCS12 p12 = new PKCS12();
                    p12.Password = p12pwd;

                    ArrayList list = new ArrayList();
                    // we use a fixed array to avoid endianess issues
                    // (in case some tools requires the ID to be 1).
                    list.Add(new byte [4] {
                        1, 0, 0, 0
                    });
                    Hashtable attributes = new Hashtable(1);
                    attributes.Add(PKCS9.localKeyId, list);

                    p12.AddCertificate(new X509Certificate(rawcert), attributes);
                    if (issuerCertificate != null)
                    {
                        p12.AddCertificate(issuerCertificate);
                    }
                    p12.AddPkcs8ShroudedKeyBag(subjectKey, attributes);

                    /*var x509cert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2();
                     * x509cert2.Import(p12.GetBytes(), "",
                     *      System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.PersistKeySet| System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable );
                     * return  x509cert2;*/
                    //return p12.GetBytes();
                    return(p12);
                }
                Logger.Append("HUBRN", Severity.INFO, "Created requested key/cert for '" + subjectName + "'.");
            }
            catch (Exception e) {
                Logger.Append("HUBRN", Severity.ERROR, "Error generating certificate for '" + subjectName + "' : " + e.ToString());
            }
            return(null);
        }