Mono.Tools.MakeCert.MakeCertMain C# (CSharp) Method

MakeCertMain() private method

private MakeCertMain ( string args ) : int
args string
return int
        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;
        }