Пример #1
0
        public static List <KeyValuePair <object, object> > EncodeSubject(string value)
        {
            X509Name name;
            object   val;
            List <KeyValuePair <object, object> > list = new List <KeyValuePair <object, object> >();

            foreach (string tmp in value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                string[] it = tmp.Split(new char[] { '=' });
                if (it.Length != 2)
                {
                    throw new ArgumentException("Invalid subject.");
                }
                name = (X509Name)Enum.Parse(typeof(X509Name), it[0].Trim());
                switch (name)
                {
                case X509Name.C:
                    // Country code is printable string
                    val = it[1].Trim();
                    break;

                case X509Name.E:
                    // email address in Verisign certificates
                    val = new GXAsn1Ia5String(it[1].Trim());
                    break;

                default:
                    val = new GXAsn1Utf8String(it[1].Trim());
                    break;
                }
                string oid = X509NameConverter.GetString(name);
                list.Add(new KeyValuePair <object, object>(new GXAsn1ObjectIdentifier(oid), val));
            }
            return(list);
        }
Пример #2
0
        //  https://tools.ietf.org/html/rfc5280#section-4.1
        private void Init(byte[] data)
        {
            rawData = data;
            GXAsn1Sequence seq = (GXAsn1Sequence)GXAsn1Converter.FromByteArray(data);

            if (seq.Count != 3)
            {
                throw new GXDLMSCertificateException("Invalid Certificate Version. Wrong number of elements in sequence.");
            }
            if (!(seq[0] is GXAsn1Sequence))
            {
                PkcsType type = GXAsn1Converter.GetCertificateType(data, seq);
                switch (type)
                {
                case PkcsType.Pkcs8:
                    throw new GXDLMSCertificateException("Invalid Certificate. This is PKCS 8 private key, not x509 certificate.");

                case PkcsType.Pkcs10:
                    throw new GXDLMSCertificateException("Invalid Certificate. This is PKCS 10 certification requests, not x509 certificate.");
                }
                throw new GXDLMSCertificateException("Invalid Certificate Version.");
            }
            GXAsn1Sequence reqInfo = (GXAsn1Sequence)seq[0];

            if ((reqInfo[0] is GXAsn1Integer))
            {
                throw new GXDLMSCertificateException("Invalid Certificate. DLMS certificate version number must be 3.");
            }
            Version = (CertificateVersion)((GXAsn1Context)reqInfo[0])[0];
            if (reqInfo[1] is sbyte)
            {
                SerialNumber = Convert.ToUInt64(reqInfo[1]);
            }
            else
            {
                SerialNumber = new BigInteger(((GXAsn1Integer)reqInfo[1]).Value);
            }
            string tmp = ((GXAsn1Sequence)reqInfo[2])[0].ToString();

            // Signature Algorithm
            SignatureAlgorithm = HashAlgorithmConverter.FromString(tmp);
            if (SignatureAlgorithm != HashAlgorithm.Sha256WithEcdsa)
            {
                throw new Exception("DLMS certificate must be signed with ecdsa-with-SHA256.");
            }
            // Optional.
            if (((GXAsn1Sequence)reqInfo[2]).Count > 1)
            {
                SignatureParameters = ((GXAsn1Sequence)reqInfo[2])[1];
            }
            // Issuer
            Issuer = GXAsn1Converter.GetSubject((GXAsn1Sequence)reqInfo[3]);
            bool basicConstraintsExists = false;

            // Validity
            ValidFrom = (DateTime)((GXAsn1Sequence)reqInfo[4])[0];
            ValidTo   = (DateTime)((GXAsn1Sequence)reqInfo[4])[1];
            Subject   = GXAsn1Converter.GetSubject((GXAsn1Sequence)reqInfo[5]);
            string CN = X509NameConverter.GetString(X509Name.CN);
            // Subject public key Info
            GXAsn1Sequence subjectPKInfo = (GXAsn1Sequence)reqInfo[6];

            PublicKey = GXPublicKey.FromRawBytes(((GXAsn1BitString)subjectPKInfo[1]).Value);
            GXEcdsa.Validate(PublicKey);
            // Get Standard Extensions.
            if (reqInfo.Count > 7)
            {
                foreach (GXAsn1Sequence s in (GXAsn1Sequence)((GXAsn1Context)reqInfo[7])[0])
                {
                    GXAsn1ObjectIdentifier id = (GXAsn1ObjectIdentifier)s[0];
                    object value          = s[1];
                    X509CertificateType t = X509CertificateTypeConverter.FromString(id.ToString());
                    switch (t)
                    {
                    case X509CertificateType.SubjectKeyIdentifier:
                        SubjectKeyIdentifier = (byte[])value;
                        break;

                    case X509CertificateType.AuthorityKeyIdentifier:
                        foreach (GXAsn1Context it in (GXAsn1Sequence)value)
                        {
                            switch (it.Index)
                            {
                            case 0:
                                //Authority Key Identifier.
                                AuthorityKeyIdentifier = (byte[])it[0];
                                break;

                            case 1:
                            {
                                StringBuilder sb = new StringBuilder();
                                //authorityCertIssuer
                                foreach (KeyValuePair <object, object> it2 in ((GXAsn1Sequence)((GXAsn1Context)it[0])[0]))
                                {
                                    if (sb.Length != 0)
                                    {
                                        sb.Append(", ");
                                    }
                                    sb.Append(X509NameConverter.FromString(Convert.ToString(it2.Key)));
                                    sb.Append("=");
                                    sb.Append(Convert.ToString(it2.Value));
                                }
                                AuthorityCertIssuer = sb.ToString();
                            }
                            break;

                            case 2:
                                //Authority cert serial number .
                                AuthorityCertificationSerialNumber = (byte[])it[0];
                                break;

                            default:
                                throw new ArgumentOutOfRangeException("Invalid context." + it.Index);
                            }
                        }
                        break;

                    case X509CertificateType.KeyUsage:
                        if (value is GXAsn1BitString)
                        {
                            // critical is optional. BOOLEAN DEFAULT FALSE,
                            KeyUsage = (KeyUsage)((GXAsn1BitString)value).ToInteger();
                        }
                        else if (value is bool?)
                        {
                            value    = s[2];
                            KeyUsage = (KeyUsage)((GXAsn1BitString)value).ToInteger();
                        }
                        else
                        {
                            throw new ArgumentException("Invalid key usage.");
                        }
                        break;

                    case X509CertificateType.BasicConstraints:
                        basicConstraintsExists = true;
                        if (value is GXAsn1Sequence)
                        {
                            if (((GXAsn1Sequence)value).Count != 0)
                            {
                                BasicConstraints = (bool)((GXAsn1Sequence)value)[0];
                            }
                        }
                        else if (value is bool?)
                        {
                            BasicConstraints = (bool)value;
                        }
                        else
                        {
                            throw new ArgumentException("Invalid key usage.");
                        }
                        break;

                    default:
                        System.Diagnostics.Debug.WriteLine("Unknown extensions: " + t.ToString());
                        break;
                    }
                }
            }
            if (!basicConstraintsExists)
            {
                // Verify that subject Common Name includes system title.
                bool commonNameFound = false;
                foreach (KeyValuePair <object, object> it in (GXAsn1Sequence)reqInfo[5])
                {
                    if (CN == it.Key.ToString())
                    {
                        if (Convert.ToString(it.Value).Length != 16)
                        {
                            throw new GXDLMSCertificateException("System title is not included in Common Name.");
                        }
                        commonNameFound = true;
                        break;
                    }
                }
                if (!commonNameFound)
                {
                    throw new GXDLMSCertificateException("Common name doesn't exist.");
                }
            }

            if (KeyUsage == KeyUsage.None)
            {
                throw new Exception("Key usage not present. It's mandotory.");
            }
            if ((KeyUsage & (KeyUsage.KeyCertSign | KeyUsage.CrlSign)) != 0 && !basicConstraintsExists)
            {
                throw new Exception("Basic Constraints value not present. It's mandotory.");
            }
            PublicKeyAlgorithm = HashAlgorithmConverter.FromString(((GXAsn1Sequence)seq[1])[0].ToString());
            if (PublicKeyAlgorithm != HashAlgorithm.Sha256WithEcdsa)
            {
                throw new Exception("DLMS certificate must be signed with ecdsa-with-SHA256.");
            }
            // Optional.
            if (((GXAsn1Sequence)seq[1]).Count > 1)
            {
                PublicKeyParameters = ((GXAsn1Sequence)seq[1])[1];
            }
            /////////////////////////////
            //Get signature.
            Signature = ((GXAsn1BitString)seq[2]).Value;
        }