private void Init(byte[] data) { GXAsn1Sequence seq = (GXAsn1Sequence)GXAsn1Converter.FromByteArray(data); if (seq.Count < 3) { throw new System.ArgumentException("Wrong number of elements in sequence."); } ///////////////////////////// // CertificationRequestInfo ::= SEQUENCE { // version INTEGER { v1(0) } (v1,...), // subject Name, // subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, // attributes [0] Attributes{{ CRIAttributes }} // } GXAsn1Sequence reqInfo = (GXAsn1Sequence)seq[0]; Version = (CertificateVersion)(sbyte)reqInfo[0]; Subject = GXAsn1Converter.GetSubject((GXAsn1Sequence)reqInfo[1]); // subject Public key info. GXAsn1Sequence subjectPKInfo = (GXAsn1Sequence)reqInfo[2]; if (reqInfo.Count > 3) { Attributes = reqInfo[3]; } GXAsn1Sequence tmp = (GXAsn1Sequence)subjectPKInfo[0]; Algorithm = PkcsObjectIdentifierConverter.FromString(tmp[0].ToString()); if ((PkcsObjectIdentifier)Algorithm == PkcsObjectIdentifier.None) { Algorithm = X9ObjectIdentifierConverter.FromString(tmp[0].ToString()); } byte[] encodedKey = GXAsn1Converter.ToByteArray(subjectPKInfo); PublicKey = GXPublicKey.FromRawBytes(encodedKey); ///////////////////////////// // signatureAlgorithm GXAsn1Sequence sign = (GXAsn1Sequence)seq[1]; SignatureAlgorithm = HashAlgorithmConverter.FromString(sign[0].ToString()); if (sign.Count != 1) { SignatureParameters = sign[1]; } ///////////////////////////// // signature Signature = ((GXAsn1BitString)seq[2]).Value; GXEcdsa e = new GXEcdsa(PublicKey); if (!e.Verify(GXAsn1Converter.ToByteArray(reqInfo), data)) { throw new ArgumentException("Invalid Signature."); } }
private void Init(byte[] data) { Attributes = new List <KeyValuePair <PkcsObjectIdentifier, object[]> >(); GXAsn1Sequence seq = (GXAsn1Sequence)GXAsn1Converter.FromByteArray(data); if (seq.Count < 3) { throw new System.ArgumentException("Wrong number of elements in sequence."); } ///////////////////////////// // CertificationRequestInfo ::= SEQUENCE { // version INTEGER { v1(0) } (v1,...), // subject Name, // subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, // attributes [0] Attributes{{ CRIAttributes }} // } GXAsn1Sequence reqInfo = (GXAsn1Sequence)seq[0]; Version = (CertificateVersion)(sbyte)reqInfo[0]; Subject = GXAsn1Converter.GetSubject((GXAsn1Sequence)reqInfo[1]); // subject Public key info. GXAsn1Sequence subjectPKInfo = (GXAsn1Sequence)reqInfo[2]; if (reqInfo.Count > 3) { //PkcsObjectIdentifier foreach (GXAsn1Sequence it in (GXAsn1Context)reqInfo[3]) { List <object> values = new List <object>(); foreach (object v in (List <object>)((KeyValuePair <object, object>)it[1]).Key) { values.Add(v); } Attributes.Add(new KeyValuePair <PkcsObjectIdentifier, object[]>(PkcsObjectIdentifierConverter.FromString(it[0].ToString()), values.ToArray())); } } GXAsn1Sequence tmp = (GXAsn1Sequence)subjectPKInfo[0]; Algorithm = X9ObjectIdentifierConverter.FromString(tmp[0].ToString()); if (Algorithm != X9ObjectIdentifier.IdECPublicKey) { object algorithm = Algorithm; if (Algorithm == X9ObjectIdentifier.None) { algorithm = PkcsObjectIdentifierConverter.FromString(tmp[0].ToString()); if ((PkcsObjectIdentifier)algorithm == PkcsObjectIdentifier.None) { algorithm = tmp[0].ToString(); } } throw new Exception("Invalid PKCS #10 certificate algorithm. " + algorithm); } PublicKey = GXPublicKey.FromRawBytes(((GXAsn1BitString)subjectPKInfo[1]).Value); GXEcdsa.Validate(PublicKey); ///////////////////////////// // signatureAlgorithm GXAsn1Sequence sign = (GXAsn1Sequence)seq[1]; SignatureAlgorithm = HashAlgorithmConverter.FromString(sign[0].ToString()); if (SignatureAlgorithm != HashAlgorithm.Sha256WithEcdsa && SignatureAlgorithm != HashAlgorithm.Sha384WithEcdsa) { throw new GXDLMSCertificateException("Invalid signature algorithm. " + sign[0].ToString()); } if (sign.Count != 1) { SignatureParameters = sign[1]; } ///////////////////////////// // signature Signature = ((GXAsn1BitString)seq[2]).Value; GXEcdsa e = new GXEcdsa(PublicKey); GXAsn1Sequence tmp2 = (GXAsn1Sequence)GXAsn1Converter.FromByteArray(Signature); GXByteBuffer bb = new GXByteBuffer(); int size = SignatureAlgorithm == HashAlgorithm.Sha256WithEcdsa ? 32 : 48; //Some implementations might add extra byte. It must removed. bb.Set(((GXAsn1Integer)tmp2[0]).Value, ((GXAsn1Integer)tmp2[0]).Value.Length == size ? 0 : 1, size); bb.Set(((GXAsn1Integer)tmp2[1]).Value, ((GXAsn1Integer)tmp2[1]).Value.Length == size ? 0 : 1, size); if (!e.Verify(bb.Array(), GXAsn1Converter.ToByteArray(reqInfo))) { throw new ArgumentException("Invalid Signature."); } }
// 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; }
// https://tools.ietf.org/html/rfc5280#section-4.1 private void Init(byte[] data) { GXAsn1Sequence seq = (GXAsn1Sequence)GXAsn1Converter.FromByteArray(data); if (seq.Count != 3) { throw new ArgumentException("Wrong number of elements in sequence."); } GXAsn1Sequence reqInfo = (GXAsn1Sequence)seq[0]; Version = (CertificateVersion)((GXAsn1Context)reqInfo[0])[0]; if (reqInfo[1] is sbyte) { SerialNumber = new GXAsn1Integer(Convert.ToUInt64(reqInfo[1])); } else { SerialNumber = (GXAsn1Integer)reqInfo[1]; } 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]); // Validity ValidFrom = (DateTime)((GXAsn1Sequence)reqInfo[4])[0]; ValidTo = (DateTime)((GXAsn1Sequence)reqInfo[4])[1]; Subject = GXAsn1Converter.GetSubject((GXAsn1Sequence)reqInfo[5]); // Subject public key Info GXAsn1Sequence subjectPKInfo = (GXAsn1Sequence)reqInfo[6]; PublicKey = GXPublicKey.FromRawBytes(((GXAsn1BitString)subjectPKInfo[1]).Value); // 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]; Enums.X509CertificateType t = Enums.X509CertificateTypeConverter.FromString(id.ToString()); switch (t) { case Enums.X509CertificateType.SubjectKeyIdentifier: SubjectKeyIdentifier = (byte[])value; break; case Enums.X509CertificateType.AuthorityKeyIdentifier: AuthorityKeyIdentifier = (byte[])((GXAsn1Sequence)value)[0]; break; case Enums.X509CertificateType.KeyUsage: if (value is GXAsn1BitString) { // critical is optional. BOOLEAN DEFAULT FALSE, KeyUsage = (KeyUsage)((GXAsn1BitString)value).Value[0]; } else if (value is bool?) { value = s[2]; KeyUsage = (KeyUsage)((GXAsn1BitString)value).Value[0]; } else { throw new ArgumentException("Invalid key usage."); } break; default: System.Diagnostics.Debug.WriteLine("Unknown extensions: " + t.ToString()); break; } } } if (KeyUsage == KeyUsage.None) { throw new Exception("Key usage not present."); } PublicKeySignature = HashAlgorithmConverter.FromString(((GXAsn1Sequence)seq[1])[0].ToString()); // Optional. if (((GXAsn1Sequence)seq[1]).Count > 1) { SignatureParameters = ((GXAsn1Sequence)seq[1])[1]; } // signature Signature = ((GXAsn1BitString)seq[2]).Value; }