예제 #1
0
        void m_initialize(Oid oid, Int32 majorVersion, Int32 minorVersion)
        {
            Oid = _eoid;
            Asn1Utils.EncodeObjectIdentifier(oid);
            Wincrypt.CERT_TEMPLATE_EXT pvStructInfo = new Wincrypt.CERT_TEMPLATE_EXT {
                pszObjId       = oid.Value,
                dwMajorVersion = (UInt32)majorVersion,
                dwMinorVersion = (UInt32)minorVersion,
                fMinorVersion  = true
            };
            UInt32 pcbEncoded = 0;

            if (Crypt32.CryptEncodeObject(1, "1.3.6.1.4.1.311.21.7", ref pvStructInfo, null, ref pcbEncoded))
            {
                RawData = new Byte[pcbEncoded];
                Crypt32.CryptEncodeObject(1, "1.3.6.1.4.1.311.21.7", ref pvStructInfo, RawData, ref pcbEncoded);
                TemplateOid  = new Oid(pvStructInfo.pszObjId);
                MajorVersion = majorVersion;
                MinorVersion = minorVersion;
            }
            else
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
        }
예제 #2
0
        /// <summary>
        /// Encodes current object to ASN.1-encoded byte array.
        /// </summary>
        /// <returns>ASN.1-encoded byte array.</returns>
        public Byte[] Encode()
        {
            List <Byte> list = new List <Byte>(Asn1Utils.Encode(RawData, 49));

            list.InsertRange(0, Asn1Utils.EncodeObjectIdentifier(Oid));
            return(Asn1Utils.Encode(list.ToArray(), 48));
        }
예제 #3
0
        /// <summary>
        /// Encodes current object to a ASN.1-encoded byte array.
        /// </summary>
        /// <returns>ASN.1-encoded byte array.</returns>
        /// <remarks>
        /// Explicit notice text is always encoded as a <strong>BMPString</strong>.
        /// <para>Notice reference is encoded in the following sequence: attempts to encode a string as a
        /// <strong>VisibleString</strong> and then as a <strong>BMPString</strong> if <strong>VisibleString</strong> fails.</para>
        /// </remarks>
        public Byte[] Encode()
        {
            switch (Type)
            {
            case X509PolicyQualifierType.CpsUrl:
                if (String.IsNullOrEmpty(PolicyUrl.AbsoluteUri))
                {
                    throw new UninitializedObjectException();
                }
                List <Byte> rawData = new List <Byte>();
                rawData.AddRange(Asn1Utils.EncodeObjectIdentifier(new Oid("1.3.6.1.5.5.7.2.1")));
                rawData.AddRange(Asn1Utils.EncodeIA5String(PolicyUrl.AbsoluteUri));
                return(Asn1Utils.Encode(rawData.ToArray(), 48));

            case X509PolicyQualifierType.UserNotice:
                List <Byte> refpart = new List <Byte>();
                if (!String.IsNullOrEmpty(NoticeReference))
                {
                    refpart.AddRange(EncodeString(NoticeReference));
                    refpart.AddRange(Asn1Utils.Encode(new Asn1Integer(NoticeNumber).RawData, 48));
                    refpart = new List <Byte>(Asn1Utils.Encode(refpart.ToArray(), 48));
                }
                if (!String.IsNullOrEmpty(NoticeText))
                {
                    refpart.AddRange(Asn1Utils.EncodeBMPString(NoticeText));
                }
                List <Byte> oid = new List <Byte>();
                oid.AddRange(Asn1Utils.EncodeObjectIdentifier(new Oid("1.3.6.1.5.5.7.2.2")));
                oid.AddRange(Asn1Utils.Encode(refpart.ToArray(), 48));
                return(Asn1Utils.Encode(oid.ToArray(), 48));

            default: throw new UninitializedObjectException();
            }
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the Oid2 class using the specified Oid friendly name or value, OID registration group and search conditions.
        /// </summary>
        /// <param name="oid">Specifies the object identifier friendly name or value to search.</param>
        /// <param name="group">Specifies the OID registration group to search.</param>
        /// <param name="searchInDirectory">Specifies whether to search for an object identifier in Active Directory. If the machine is not
        /// domain-joined, an OID is searched by using local registration information.</param>
        public Oid2(String oid, OidGroupEnum group, Boolean searchInDirectory)
        {
            var flatOid = new Oid(oid);

            try {
                // try to validate if input OID contains OID value instead of friendly name
                Asn1Utils.EncodeObjectIdentifier(flatOid);
                oid       = flatOid.Value;
                _searchBy = "ByValue";
            } catch {
                _searchBy = "ByName";
            }

            if (Environment.OSVersion.Version.Major >= 6)
            {
                _cng = true;
            }
            if (searchInDirectory)
            {
                if (DsUtils.Ping())
                {
                    initializeDS(oid, group);
                }
                else
                {
                    initializeLocal(oid, group);
                }
            }
            else
            {
                initializeLocal(oid, group);
            }
        }
예제 #5
0
 void encodeRegisteredId(Object value) {
     if (value == null) {
         rawData = new Byte[] { 136, 0 };
     } else {
         Asn1Reader asn;
         switch (value) {
             case String sValue:
                 Value = sValue;
                 Oid oid = new Oid(sValue);
                 asn = new Asn1Reader(Asn1Utils.EncodeObjectIdentifier(oid));
                 Value = oid.Value;
                 break;
             case Oid oid1:
                 asn = new Asn1Reader(Asn1Utils.EncodeObjectIdentifier(oid1));
                 Value = oid1.Value;
                 break;
             case Oid2 oid2:
                 asn = new Asn1Reader(Asn1Utils.EncodeObjectIdentifier(new Oid(oid2.Value)));
                 Value = oid2.Value;
                 break;
             default: throw new ArgumentException("The input data is not valid registered ID.");
         }
         rawData = Asn1Utils.Encode(asn.GetPayload(), 136);
     }
 }
예제 #6
0
        void encodeRegisteredId(Object value)
        {
            if (value == null)
            {
                RawData = new Byte[] { 136, 0 };
            }
            else
            {
                Asn1Reader asn;
                switch (value.GetType().FullName)
                {
                case "System.String":
                    Value = (String)value;
                    Oid oid = new Oid((String)value);
                    asn   = new Asn1Reader(Asn1Utils.EncodeObjectIdentifier(oid));
                    Value = oid.Value;
                    break;

                case "System.Security.Oid":
                    asn   = new Asn1Reader(Asn1Utils.EncodeObjectIdentifier((Oid)value));
                    Value = ((Oid)value).Value;
                    break;

                case "System.Security.Oid2":
                    asn   = new Asn1Reader(Asn1Utils.EncodeObjectIdentifier(new Oid(((Oid2)value).Value)));
                    Value = ((Oid2)value).Value;
                    break;

                default: throw new ArgumentException("The input data is not valid registered ID.");
                }
                RawData = Asn1Utils.Encode(asn.GetPayload(), 136);
            }
        }
예제 #7
0
        /// <summary>
        /// Gets ASN.1-encoded byte array that represents OID mapping.
        /// </summary>
        /// <returns>ASN.1-encoded byte array.</returns>
        public Byte[] Encode()
        {
            List <Byte> entry = new List <Byte>();

            entry.AddRange(Asn1Utils.EncodeObjectIdentifier(IssuerDomainOid));
            entry.AddRange(Asn1Utils.EncodeObjectIdentifier(SubjectDomainOid));
            return(Asn1Utils.Encode(entry.ToArray(), 48));
        }
예제 #8
0
        void m_encode(Oid oid, Byte[] parameters)
        {
            Parameters  = parameters;
            AlgorithmId = oid;
            List <Byte> rawBytes = new List <Byte>(Asn1Utils.EncodeObjectIdentifier(oid));

            rawBytes.AddRange(Parameters);
            RawData = Asn1Utils.Encode(rawBytes.ToArray(), 48);
        }
예제 #9
0
        void m_initialize(IEnumerable <String> authorityIssuer, IEnumerable <String> ocsp, Boolean ocspFirst)
        {
            Oid      = _oid;
            Critical = false;
            var aiaUrlStrings  = new List <String>();
            var ocspUrlStrings = new List <String>();

            Byte[] aiaOidBytes  = Asn1Utils.EncodeObjectIdentifier(new Oid("1.3.6.1.5.5.7.48.2"));
            Byte[] ocspOidBytes = Asn1Utils.EncodeObjectIdentifier(new Oid("1.3.6.1.5.5.7.48.1"));
            var    aiaBytes     = new List <Byte>();
            var    ocspBytes    = new List <Byte>();

            if (authorityIssuer != null)
            {
                foreach (Uri uri in authorityIssuer.Select(url => new Uri(url)))
                {
                    aiaUrlStrings.Add(uri.AbsoluteUri);
                    aiaBytes.AddRange(aiaOidBytes);
                    aiaBytes.AddRange(Asn1Utils.Encode(Encoding.ASCII.GetBytes(uri.AbsoluteUri), 134));
                    aiaBytes = new List <Byte>(Asn1Utils.Encode(aiaBytes.ToArray(), 48));
                }
                CertificationAuthorityIssuer = aiaUrlStrings.ToArray();
            }
            else
            {
                CertificationAuthorityIssuer = Array.Empty <String>();
            }
            if (ocsp != null)
            {
                foreach (Uri uri in ocsp.Select(url => new Uri(url)))
                {
                    ocspUrlStrings.Add(uri.AbsoluteUri);
                    ocspBytes.AddRange(ocspOidBytes);
                    ocspBytes.AddRange(Asn1Utils.Encode(Encoding.ASCII.GetBytes(uri.AbsoluteUri), 134));
                    ocspBytes = new List <Byte>(Asn1Utils.Encode(ocspBytes.ToArray(), 48));
                }
                OnlineCertificateStatusProtocol = ocspUrlStrings.ToArray();
            }
            else
            {
                OnlineCertificateStatusProtocol = Array.Empty <String>();
            }
            List <Byte> rawData;

            if (ocspFirst)
            {
                ocspBytes.AddRange(aiaBytes.ToArray());
                rawData = ocspBytes;
            }
            else
            {
                aiaBytes.AddRange(ocspBytes.ToArray());
                rawData = aiaBytes;
            }
            RawData = Asn1Utils.Encode(rawData.ToArray(), 48);
        }
예제 #10
0
		void m_initialize(OidCollection applicationPolicies, Boolean critical) {
			Oid = _oid;
			Critical = critical;
			List<Byte> rawData = new List<Byte>();
			foreach (Oid aoid in applicationPolicies.Cast<Oid>().Where(aoid => !String.IsNullOrEmpty(aoid.Value))) {
				_oids.Add(aoid);
				rawData.AddRange(Asn1Utils.Encode(Asn1Utils.EncodeObjectIdentifier(aoid), 48));
			}
			RawData = Asn1Utils.Encode(rawData.ToArray(), 48);
		}
예제 #11
0
        // specific name types encoders
        void encodeOtherName(Object value, Oid oid)
        {
            Byte[] rawBytes;
            if (value as String != null)
            {
                rawBytes = Encoding.UTF8.GetBytes((String)value);
            }
            else if (value as Byte[] != null)
            {
                rawBytes = (Byte[])value;
            }
            else
            {
                rawBytes = new Byte[0];
            }
            Asn1Type tag;

            switch (oid.Value)
            {
            // UPN
            case "1.3.6.1.4.1.311.20.2.3":
                tag  = Asn1Type.UTF8String;
                Type = X509AlternativeNamesEnum.UserPrincipalName;
                break;

            // Guid
            case "1.3.6.1.4.1.311.25.1":
                tag  = Asn1Type.OCTET_STRING;
                Type = X509AlternativeNamesEnum.Guid;
                break;

            // Other name;
            default:
                Value = String.Empty;
                foreach (Byte B in rawBytes)
                {
                    Value += $"{B:x2}" + " ";
                }
                Value = Value.Trim();
                tag   = Asn1Type.OCTET_STRING;
                Type  = X509AlternativeNamesEnum.OtherName;
                break;
            }
            if (String.IsNullOrEmpty(Value))
            {
                Value = Encoding.UTF8.GetString(rawBytes);
            }
            OID     = oid;
            RawData = Asn1Utils.Encode(rawBytes, (Byte)tag);
            RawData = Asn1Utils.Encode(RawData, 160);
            List <Byte> tempBytes = new List <Byte>(Asn1Utils.EncodeObjectIdentifier(oid));

            tempBytes.AddRange(RawData);
            RawData = Asn1Utils.Encode(tempBytes.ToArray(), 160);
        }
예제 #12
0
        /// <summary>
        /// Removes certificate extension object identifier (OID) value from a specified extension group.
        /// </summary>
        /// <param name="extensionType">Specifies the extension type. Possible values are: <strong>EnabledExtensionList</strong>, <strong>OfflineExtensionList</strong>
        /// and <strong>DisabledExtensionList</strong>.
        /// <para>If extension is removed, <see cref="IsModified"/> property is set to <strong>True</strong>.</para></param>
        /// <param name="oid">Certificate extension object identifier.</param>
        /// <exception cref="ArgumentNullException">The <strong>extensionType</strong> parameter is <strong>Null</strong>.</exception>
        /// <exception cref="ArgumentException">The <strong>extensionType</strong> parameter value is incorrect, or <strong>oid</strong> parameter is invalid
        /// object identifier.</exception>
        public void Remove(String extensionType, Oid oid)
        {
            if (String.IsNullOrEmpty(Name))
            {
                throw new UninitializedObjectException();
            }
            try { Asn1Utils.EncodeObjectIdentifier(oid); }
            catch { throw new ArgumentException("Specified object identifier is not valid or is not resolvable"); }
            if (String.IsNullOrEmpty(extensionType))
            {
                throw new ArgumentNullException(nameof(extensionType));
            }
            List <Oid> existing;

            switch (extensionType.ToLower())
            {
            case "enabledextensionlist":
                existing = new List <Oid>(EnabledExtensionList);
                if (GenericArray.OidContains(EnabledExtensionList, oid))
                {
                    GenericArray.RemoveOid(existing, oid);
                    IsModified = true;
                }
                EnabledExtensionList = existing.ToArray();
                break;

            case "offlineextensionlist":
                existing = new List <Oid>(OfflineExtensionList);
                if (GenericArray.OidContains(EnabledExtensionList, oid))
                {
                    GenericArray.RemoveOid(existing, oid);
                    IsModified = true;
                }
                OfflineExtensionList = existing.ToArray();
                break;

            case "disabledextensionlist":
                existing = new List <Oid>(DisabledExtensionList);
                if (GenericArray.OidContains(DisabledExtensionList, oid))
                {
                    GenericArray.RemoveOid(existing, oid);
                    IsModified = true;
                }
                DisabledExtensionList = existing.ToArray();
                break;

            default:
                throw new ArgumentException(
                          "Invalid extension type is specified. Allowed types are: EnabledExtensionList, OfflineExtensionList and DisabledExtensionList.");
            }
        }
예제 #13
0
        public static Byte[] ExportBinaryData(this X509Extension extension)
        {
            if (String.IsNullOrEmpty(extension.Oid.Value))
            {
                return(null);
            }
            List <Byte> rawData = new List <Byte>(Asn1Utils.EncodeObjectIdentifier(extension.Oid));

            if (extension.Critical)
            {
                rawData.AddRange(Asn1Utils.EncodeBoolean(true));
            }
            rawData.AddRange(Asn1Utils.Encode(extension.RawData, (Byte)Asn1Type.OCTET_STRING));
            return(Asn1Utils.Encode(rawData.ToArray(), 48));
        }
예제 #14
0
        /// <summary>
        /// Registers object identifier in the OID database, either, local or in Active Directory.
        /// </summary>
        /// <param name="value">An object identifier value to register.</param>
        /// <param name="friendlyName">A friendly name associated with the object identifier.</param>
        /// <param name="group">Specifies the OID group where specified object identifier should be registered.</param>
        /// <param name="writeInDirectory">Specifies, whether object is registered locally or in Active Directory.</param>
        /// <param name="localeId">
        ///		Specifies the locale ID. This parameter can be used to provide localized friendly name. This parameter can
        ///		be used only when <strong>writeInDirectory</strong> is set to <strong>True</strong> in other cases it is
        ///		silently ignored.
        /// </param>
        /// <param name="cpsUrl">
        ///		Specifies the URL to a <i>certificate practice statement</i> (<strong>CPS</strong>) location.
        /// </param>
        /// <exception cref="ArgumentNullException">
        ///		<strong>value</strong> and/or <strong>friendlyName</strong> is null or empty.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///		Specified OID group is not supported. See <strong>Remarks</strong> section for more details.
        /// </exception>
        /// <exception cref="InvalidDataException"><strong>value</strong> parameter is not object idnetifier value.</exception>
        /// <exception cref="NotSupportedException">
        ///		A caller chose OID registration in Active Directory, however, the current computer is not a member of any
        ///		Active Directory domain.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        ///		An object identifier is already registered.
        /// </exception>
        /// <remarks>
        /// <para>
        /// <strong>Permissions:</strong> for this method to succeed, the caller must be a member of the local
        /// administrators group (if <strong>writeInDirectory</strong> is set to <strong>False</strong>) or
        /// be a member of <strong>Enterprise Admins</strong> group or has delegated write permissions on the
        /// <strong>OID</strong> container in Active Directory. OID container location is
        /// <i>CN=OID, CN=Public Key Services, CN=Services,CN=Configuration, {Configuration naming context}</i>.
        /// </para>
        /// <para>
        ///		A newly registered OID is not resolvable by an application immediately. You may need to restart an application
        ///		to allow new OID lookup.
        /// </para>
        /// <para>
        ///		When <strong>writeInDirectory</strong> is set to <strong>True</strong>, <strong>group</strong> parameter
        ///		is limited only to one of the following value: <strong>ApplicationPolicy</strong>,<strong>IssuancePolicy</strong>
        ///		and <strong>CertificateTemplate</strong>. Other OID groups are not allowed to be stored in Active Directory.
        /// </para>
        /// </remarks>
        /// <returns>Registered object identifier.</returns>
        public static Oid2 Register(String value, String friendlyName, OidGroupEnum group, Boolean writeInDirectory, CultureInfo localeId, String cpsUrl = null)
        {
            if (String.IsNullOrEmpty(value))
            {
                throw new ArgumentNullException(nameof(value));
            }
            if (String.IsNullOrEmpty(friendlyName))
            {
                throw new ArgumentNullException(nameof(friendlyName));
            }
            try {
                Asn1Utils.EncodeObjectIdentifier(new Oid(value));
            } catch {
                throw new InvalidDataException("The value is not valid OID string.");
            }

            String cn = null;

            if (writeInDirectory)
            {
                if (!DsUtils.Ping())
                {
                    throw new NotSupportedException("Workgroup environment is not supported.");
                }
                if (!String.IsNullOrEmpty(new Oid2(value, group, true).DistinguishedName))
                {
                    throw new InvalidOperationException("The object already exist.");
                }
                List <Int32> exclude = new List <Int32>(new[] { 0, 1, 2, 3, 4, 5, 6, 9, 10 });
                if (exclude.Contains((Int32)group))
                {
                    throw new ArgumentException("The OID group is not valid.");
                }
                registerDS(new Oid(value, friendlyName), group, localeId, cpsUrl);
                cn = "CN=" + computeOidHash(value) + ",CN=OID," + DsUtils.ConfigContext;
            }
            else
            {
                registerLocal(new Oid(value, friendlyName), group);
            }
            return(new Oid2 {
                FriendlyName = friendlyName,
                Value = value,
                OidGroup = group,
                DistinguishedName = cn
            });
        }
예제 #15
0
        /// <summary>
        /// Gets all registrations for the specified OID value.
        /// </summary>
        /// <param name="value">OID value to search. If the OID name is passed, it is converted to a best OID value
        /// match and performs OID search by it's value.</param>
        /// <param name="searchInDirectory">
        /// Specifies whether to search for an object identifier in Active Directory. If the machine is not
        /// domain-joined, an OID is searched by using local registration information.
        /// </param>
        /// <exception cref="ArgumentException">
        /// The <strong>value</strong> parameter contains unresolvable object identifier friendly name.
        /// </exception>
        /// <returns>An array of OID registrations.</returns>
        /// <remarks>
        /// If registration information is found in Active Directory, <strong>DistinguishedName</strong> parameter contains
        /// directory path to a OID registration entry.
        /// </remarks>
        public static Oid2[] GetAllOids(String value, Boolean searchInDirectory)
        {
            String oidvalue;

            try {
                Asn1Utils.EncodeObjectIdentifier(new Oid(value));
                oidvalue = value;
            } catch {
                var oid = new Oid(value);
                if (String.IsNullOrEmpty(oid.Value))
                {
                    throw new ArgumentException("Specified OID value is not recognized.", nameof(value));
                }
                oidvalue = oid.Value;
            }
            return(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }.Select(group => new Oid2(oidvalue, (OidGroupEnum)group, searchInDirectory)).Where(obj => !String.IsNullOrEmpty(obj.Value)).ToArray());
        }
예제 #16
0
        void encode(Oid oid, Byte[] parameters)
        {
            // if empty array received, then parameters is set to ASN.1 NULL type => 5, 0
            param = parameters != null && parameters.Length == 0
                ? new Byte[] { 5, 0 }
                : parameters;

            algId = oid;
            var rawBytes = new List <Byte>(Asn1Utils.EncodeObjectIdentifier(oid));

            if (param != null)
            {
                rawBytes.AddRange(param);
            }

            _rawData.AddRange(Asn1Utils.Encode(rawBytes.ToArray(), 48));
        }
예제 #17
0
        public static Byte[] EncodeX509Extension(X509Extension extension)
        {
            if (extension == null)
            {
                throw new ArgumentNullException(nameof(extension));
            }
            if (String.IsNullOrEmpty(extension.Oid.Value))
            {
                throw new UninitializedObjectException();
            }
            List <Byte> rawData = new List <Byte>(Asn1Utils.EncodeObjectIdentifier(extension.Oid));

            if (extension.Critical)
            {
                rawData.AddRange(Asn1Utils.EncodeBoolean(true));
            }
            rawData.AddRange(Asn1Utils.Encode(extension.RawData, (Byte)Asn1Type.OCTET_STRING));
            return(Asn1Utils.Encode(rawData.ToArray(), 48));
        }
예제 #18
0
 /// <summary>
 /// Encodes current object to a DER-encoded byte array. Returned array is used to construct initial OCSP Request structure.
 /// </summary>
 /// <returns>Returns a DER-encoded byte array.</returns>
 /// <value>System.Byte[]</value>
 public Byte[] Encode()
 {
     if (!String.IsNullOrEmpty(SerialNumber))
     {
         if (issuerPublicKey != null)
         {
             initializeFromCertAndIssuer();
         }
         // algorithm identifier
         var rawData = new List <Byte>(Asn1Utils.EncodeObjectIdentifier(hashAlgorithm));
         rawData.AddRange(Asn1Utils.EncodeNull());
         rawData = new List <Byte>(Asn1Utils.Encode(rawData.ToArray(), 48));
         // IssuerNameId
         rawData.AddRange(Asn1Utils.Encode(AsnFormatter.StringToBinary(IssuerNameId, EncodingType.HexRaw), 4));
         // IssuerKeyId
         rawData.AddRange(Asn1Utils.Encode(AsnFormatter.StringToBinary(IssuerKeyId, EncodingType.HexRaw), 4));
         // SerialNumber
         rawData.AddRange(Asn1Utils.Encode(serialNumber, 2));
         IsReadOnly = true;
         return(Asn1Utils.Encode(rawData.ToArray(), 48));
     }
     throw new UninitializedObjectException();
 }
예제 #19
0
 void m_initialize(String policyOid, X509PolicyQualifierCollection qualifiers = null)
 {
     rawData.AddRange(Asn1Utils.EncodeObjectIdentifier(new Oid(policyOid)));
     PolicyOid        = new Oid(policyOid);
     PolicyQualifiers = qualifiers ?? new X509PolicyQualifierCollection();
 }