using GostCryptography.Properties; using System; namespace GostCryptography.Asn1.Ber { [Serializable] public class Asn1ObjectIdentifier : Asn1Type { public static readonly Asn1Tag Tag = new Asn1Tag(0, 0, ObjectIdentifierTypeCode); [NonSerialized] protected OidValue OidValue; public OidValue Oid => OidValue; public Asn1ObjectIdentifier() { OidValue = null; } public Asn1ObjectIdentifier(OidValue oidValue) { OidValue = oidValue; } public static Asn1ObjectIdentifier FromString(string value) { return string.IsNullOrEmpty(value) ? null : new Asn1ObjectIdentifier(OidValue.FromString(value)); } public override void Decode(Asn1BerDecodeBuffer buffer, bool explicitTagging, int implicitLength) { var len = explicitTagging ? MatchTag(buffer, Tag) : implicitLength; if (len <= 0) { throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidLengthException); } OidValue = OidValue.FromArray(buffer.DecodeOidContents(len)); buffer.TypeCode = ObjectIdentifierTypeCode; } public override int Encode(Asn1BerEncodeBuffer buffer, bool explicitTagging) { if (((OidValue.Items.Length < 2) || (OidValue.Items[0] > 2)) || ((OidValue.Items[0] != 2) && (OidValue.Items[1] > 0x27))) { throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException); } var len = 0; for (var i = OidValue.Items.Length - 1; i >= 1; i--) { len += buffer.EncodeIdentifier((i == 1) ? ((OidValue.Items[0] * 40) + OidValue.Items[1]) : OidValue.Items[i]); } if (explicitTagging) { len += buffer.EncodeTagAndLength(Tag, len); } return len; } public override void Encode(Asn1BerOutputStream outs, bool explicitTagging) { if (((OidValue.Items.Length < 2) || (OidValue.Items[0] > 2)) || ((OidValue.Items[0] != 2) && (OidValue.Items[1] > 0x27))) { throw ExceptionUtility.CryptographicException(Resources.Asn1InvalidObjectIdException); } var len = 1; for (var i = 2; i < OidValue.Items.Length; i++) { len += Asn1RunTime.GetIdentBytesCount(OidValue.Items[i]); } if (explicitTagging) { outs.EncodeTag(Tag); } outs.EncodeLength(len); var ident = (OidValue.Items[0] * 40) + OidValue.Items[1]; outs.EncodeIdentifier(ident); for (var i = 2; i < OidValue.Items.Length; i++) { outs.EncodeIdentifier(OidValue.Items[i]); } } public override bool Equals(object obj) { if (this == obj) { return true; } if (!(obj is Asn1ObjectIdentifier)) { return false; } var other = (Asn1ObjectIdentifier)obj; if (OidValue == other.OidValue) { return true; } if (OidValue == null || other.OidValue == null) { return false; } return OidValue.Equals(other.OidValue); } public override int GetHashCode() { return OidValue?.GetHashCode() ?? base.GetHashCode(); } public override string ToString() { return OidValue?.ToString() ?? base.ToString(); } } }