Class: Blobfish::Ejbca::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/blobfish/ejbca/client.rb

Overview

See too ‘D:dejbcatestsejbca_ws_clientsrcp12onejbcaside’ for a Java alternative for this client.

Constant Summary collapse

STATUS_NEW =
10
TOKEN_TYPE_P12 =
'P12'
TOKEN_TYPE_USERGENERATED =
'USERGENERATED'
RESPONSETYPE_CERTIFICATE =
'CERTIFICATE'
RESPONSETYPE_PKCS7WITHCHAIN =
'PKCS7WITHCHAIN'
REVOCATION_REASON_UNSPECIFIED =
0

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(wsdl_url, ws_additional_trusted_anchors, ws_client_certificate, ws_client_key, ws_client_key_password, ca_name, cert_profile, ee_profile) ⇒ Client

Returns a new instance of Client.

Parameters:

  • ws_additional_trusted_anchors (String)

    e.g. ca-certificates.crt. Required only if wsdl_url uses a non-commercial SSL certificate, otherwise it should be nil.



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/blobfish/ejbca/client.rb', line 19

def initialize(wsdl_url, ws_additional_trusted_anchors, ws_client_certificate, ws_client_key, ws_client_key_password, ca_name, cert_profile, ee_profile)
  @savon_client = Savon.client(
      wsdl: wsdl_url,
      ssl_cert_file: ws_client_certificate,
      ssl_cert_key_file: ws_client_key,
      ssl_cert_key_password: ws_client_key_password,
      ssl_ca_cert_file: ws_additional_trusted_anchors,
  # log: true,
  # log_level: :debug,
  )
  @ca_name = ca_name
  @ca_dn = query_ca_dn(ca_name)
  @cert_profile = cert_profile
  @ee_profile = ee_profile
end

Class Method Details

.escape_dn_attr_value(val) ⇒ Object



35
36
37
38
# File 'lib/blobfish/ejbca/client.rb', line 35

def self.escape_dn_attr_value(val)
  # TODO study escaping rules in detail. Take a look at relevant standards and the EJBCA implementation. See too https://sourceforge.net/p/ejbca/discussion/123123/thread/d36bb985/.
  val.gsub(",", "\\,")
end

Instance Method Details

#get_all_certs(ejbca_username) ⇒ Object

NOTE that these entries aren’t being ordered by issuance, but by the latest to expire, i.e. the latest cert to expire is returned first.



99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/blobfish/ejbca/client.rb', line 99

def get_all_certs(ejbca_username)
  certs = ws_call(:find_certs,
                  arg0: ejbca_username,
                  arg1: false,
  )
  Enumerator.new do |yielder|
    certs.each do |cert|
      cert_as_der = Client.double_decode64(cert[:certificate_data])
      yielder << Certificate.new(cert_as_der)
    end
  end
end

#get_revocation_status(serial_number) ⇒ Object



89
90
91
92
93
94
95
96
# File 'lib/blobfish/ejbca/client.rb', line 89

def get_revocation_status(serial_number)
  revocation_status = ws_call(:check_revokation_status,
                              arg0: @ca_dn,
                              arg1: serial_number,
  )
  raise "Certificate with serial number #{serial_number} doesn't exists for #{@ca_dn}" if revocation_status.nil?
  revocation_status if revocation_status[:reason].to_i != -1
end

#request_from_csr(pem_csr, ejbca_username, email_address, subject_dn, subject_alt_name, validity_type, validity_value, response_type = RESPONSETYPE_CERTIFICATE) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/blobfish/ejbca/client.rb', line 64

def request_from_csr(pem_csr, ejbca_username, email_address, subject_dn, subject_alt_name, validity_type, validity_value, response_type = RESPONSETYPE_CERTIFICATE)
  end_user = create_end_user(ejbca_username, nil, TOKEN_TYPE_USERGENERATED, email_address, subject_dn, subject_alt_name, validity_type, validity_value)
  ws_resp = ws_call(:certificate_request,
                    arg0: end_user,
                    arg1: pem_csr,
                    arg2: 0,
                    arg4: response_type)
  resp_as_der = Client.double_decode64(ws_resp[:data])
  if response_type == RESPONSETYPE_CERTIFICATE
    Certificate.new(resp_as_der)
  elsif response_type == RESPONSETYPE_PKCS7WITHCHAIN
    OpenSSL::PKCS7.new(resp_as_der)
  else
    raise NotImplementedError
  end
end

#request_pfx(ejbca_username, email_address, subject_dn, subject_alt_name, validity_type, validity_value, pfx_password, custom_friendly_name) ⇒ Object

Note that it requires ‘Allow validity override’ set in the EJBCA certificate profile for the pair validity_type,validity_value to be effective. ‘subject_dn’ should have its attributes values escaped using ‘escape_dn_attr_value’. ‘custom_friendly_name’ is optional. It can be set to ‘nil’ to maintain the one set by EJBCA (TODO confirm if EJBCA actually sets a friendly name).



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/blobfish/ejbca/client.rb', line 43

def request_pfx(ejbca_username, email_address, subject_dn, subject_alt_name, validity_type, validity_value, pfx_password, custom_friendly_name)
  end_user = create_end_user(ejbca_username, pfx_password, TOKEN_TYPE_P12, email_address, subject_dn, subject_alt_name, validity_type, validity_value)
  ws_call(:edit_user,
          arg0: end_user)
  ws_resp = ws_call(:pkcs12_req,
                    arg0: ejbca_username,
                    arg1: pfx_password,
                    arg3: '2048',
                    arg4: 'RSA'
  )
  pfx_bytes = Client.double_decode64(ws_resp[:keystore_data])
  pkcs12 = OpenSSL::PKCS12.new(pfx_bytes, pfx_password)
  unless custom_friendly_name.nil?
    # NOTE that this is currently removing the friendlyName for all bundled CA certs, but this is not expected to produce problems.
    updated_pkcs12 = OpenSSL::PKCS12.create(pfx_password, custom_friendly_name, pkcs12.key, pkcs12.certificate, pkcs12.ca_certs)
    pfx_bytes = updated_pkcs12.to_der
  end
  {pfx: pfx_bytes, cert: Certificate.new(pkcs12.certificate)}

end

#revoke_cert(serial_number) ⇒ Object



81
82
83
84
85
86
87
# File 'lib/blobfish/ejbca/client.rb', line 81

def revoke_cert(serial_number)
  ws_call(:revoke_cert,
          arg0: @ca_dn,
          arg1: serial_number,
          arg2: REVOCATION_REASON_UNSPECIFIED
  )
end