Class: Rex::Proto::X509::Request
- Inherits:
-
Object
- Object
- Rex::Proto::X509::Request
- Defined in:
- lib/rex/proto/x509/request.rb
Class Method Summary collapse
-
.build_csr(cn:, private_key:, dns: nil, msext_sid: nil, msext_upn: nil, algorithm: 'SHA256', application_policies: []) ⇒ OpenSSL::X509::Request
Make a certificate signing request.
-
.build_on_behalf_of(csr:, on_behalf_of:, cert:, key:, algorithm: 'SHA256') ⇒ Rex::Proto::CryptoAsn1::Cms::ContentInfo
Make a certificate request on behalf of another user.
- .create_csr(private_key, cn, algorithm = 'SHA256') {|request| ... } ⇒ Object
Class Method Details
.build_csr(cn:, private_key:, dns: nil, msext_sid: nil, msext_upn: nil, algorithm: 'SHA256', application_policies: []) ⇒ OpenSSL::X509::Request
Make a certificate signing request.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/rex/proto/x509/request.rb', line 38 def self.build_csr(cn:, private_key:, dns: nil, msext_sid: nil, msext_upn: nil, algorithm: 'SHA256', application_policies: []) Rex::Proto::X509::Request.create_csr(private_key, cn, algorithm) do |request| extensions = [] subject_alt_names = [] subject_alt_names << "otherName = #{OID_NT_PRINCIPAL_NAME};UTF8:#{msext_upn}" if msext_upn if msext_sid subject_alt_names << "URI = #{SAN_URL_PREFIX}#{msext_sid}" subject_alt_names << "URI = #{msext_sid}" end subject_alt_names << "DNS = #{dns}" if dns unless subject_alt_names.empty? # factory.create_extension accepts a comma separated list of SANs or a config file of SANs. # SAN_URL_PREFIX in the URI SAN contains a comma so we create a config file and add it to the factory # The config file requires an identifier we define at the top of the file [alt_names] subject_alt_names.prepend("[alt_names]") subject_alt_names_conf = subject_alt_names.join("\n") config = OpenSSL::Config.parse(subject_alt_names_conf) factory = OpenSSL::X509::ExtensionFactory.new factory.config = config extensions << factory.create_extension('subjectAltName', '@alt_names', false) end if msext_sid ntds_ca_security_ext = Rex::Proto::CryptoAsn1::NtdsCaSecurityExt.new(OtherName: { type_id: OID_NTDS_OBJECTSID, value: msext_sid }) extensions << OpenSSL::X509::Extension.new(OID_NTDS_CA_SECURITY_EXT, ntds_ca_security_ext.to_der, false) end unless application_policies.blank? application_cert_policies = Rex::Proto::CryptoAsn1::X509::CertificatePolicies.new( certificatePolicies: application_policies.map { |policy_oid| Rex::Proto::CryptoAsn1::X509::PolicyInformation.new(policyIdentifier: policy_oid) } ) extensions << OpenSSL::X509::Extension.new(OID_APPLICATION_CERT_POLICIES, application_cert_policies.to_der, false) end unless extensions.empty? request.add_attribute(OpenSSL::X509::Attribute.new( 'extReq', OpenSSL::ASN1::Set.new( [OpenSSL::ASN1::Sequence.new(extensions)] ) )) end end end |
.build_on_behalf_of(csr:, on_behalf_of:, cert:, key:, algorithm: 'SHA256') ⇒ Rex::Proto::CryptoAsn1::Cms::ContentInfo
Make a certificate request on behalf of another user.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/rex/proto/x509/request.rb', line 98 def self.build_on_behalf_of(csr:, on_behalf_of:, cert:, key:, algorithm: 'SHA256') # algorithm needs to be one that OpenSSL supports, but we also need the OID constants defined digest = OpenSSL::Digest.new(algorithm) unless [ digest.name, "RSAWith#{digest.name}" ].all? { |s| Rex::Proto::Kerberos::Model::OID.constants.include?(s.to_sym) } raise ArgumentError, "Can not map digest algorithm #{digest.name} to the necessary OIDs." end digest_oid = Rex::Proto::Kerberos::Model::OID.const_get(digest.name) signer_info = Rex::Proto::CryptoAsn1::Cms::SignerInfo.new( version: 1, sid: { issuer: cert.issuer, serial_number: cert.serial.to_i }, digest_algorithm: { algorithm: digest_oid }, signed_attrs: [ { attribute_type: OID_ENROLLMENT_NAME_VALUE_PAIR, attribute_values: [ RASN1::Types::Any.new(value: Rex::Proto::CryptoAsn1::EnrollmentNameValuePair.new( name: 'requestername', value: on_behalf_of )) ] }, { attribute_type: Rex::Proto::Kerberos::Model::OID::MessageDigest, attribute_values: [RASN1::Types::Any.new(value: RASN1::Types::OctetString.new(value: digest.digest(csr.to_der)))] } ], signature_algorithm: { algorithm: Rex::Proto::Kerberos::Model::OID.const_get("RSAWith#{digest.name}") } ) data = RASN1::Types::Set.new(value: signer_info[:signed_attrs].value).to_der signature = key.sign(digest, data) signer_info[:signature] = signature signed_data = Rex::Proto::CryptoAsn1::Cms::SignedData.new( version: 3, digest_algorithms: [ { algorithm: digest_oid } ], encap_content_info: { econtent_type: Rex::Proto::Kerberos::Model::OID::PkinitAuthData, econtent: csr.to_der }, certificates: [{ openssl_certificate: cert }], signer_infos: [signer_info] ) Rex::Proto::CryptoAsn1::Cms::ContentInfo.new( content_type: Rex::Proto::Kerberos::Model::OID::SignedData, data: signed_data ) end |
.create_csr(private_key, cn, algorithm = 'SHA256') {|request| ... } ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/rex/proto/x509/request.rb', line 16 def self.create_csr(private_key, cn, algorithm = 'SHA256') request = OpenSSL::X509::Request.new request.subject = OpenSSL::X509::Name.new([ ['CN', cn, OpenSSL::ASN1::UTF8STRING] ]) request.public_key = private_key.public_key yield request if block_given? request.sign(private_key, OpenSSL::Digest.new(algorithm)) request end |