File: certificate_request_spec.rb

package info (click to toggle)
ruby-acme-client 2.10.really.2.0.18-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,132 kB
  • sloc: ruby: 2,217; makefile: 7; sh: 3
file content (148 lines) | stat: -rw-r--r-- 5,359 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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
89
90
91
92
93
94
95
96
97
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
require 'spec_helper'

describe Acme::Client::CertificateRequest do
  let(:test_key) { generate_private_key }

  it 'reads the common name from the subject' do
    request = Acme::Client::CertificateRequest.new(private_key: test_key, subject: { common_name: 'example.org' })

    expect(request.common_name).to eq('example.org')

    request = Acme::Client::CertificateRequest.new(private_key: test_key, subject: { 'CN' => 'example.org' })

    expect(request.common_name).to eq('example.org')
  end

  it "doesn't modify the given subject" do
    subject = { common_name: 'example.org' }
    original = subject.dup
    Acme::Client::CertificateRequest.new(private_key: test_key, subject: subject)

    expect(subject).to eq(original)
  end

  it 'normalizes the subject to OpenSSL short names' do
    subject = Acme::Client::CertificateRequest::SUBJECT_KEYS.each_with_object({}) {|(key, _), hash|
      hash[key] = 'example'
    }
    request = Acme::Client::CertificateRequest.new(private_key: test_key, subject: subject)

    subject = Acme::Client::CertificateRequest::SUBJECT_KEYS.each_with_object({}) {|(_, short_name), hash|
      hash[short_name] = 'example'
    }
    expect(request.subject).to eq(subject)
  end

  it 'sets the subject common name from the parameter' do
    request = Acme::Client::CertificateRequest.new(common_name: 'example.org', private_key: test_key)

    expect(request.subject['CN']).to eq('example.org')
  end

  it 'adds the common name to the names' do
    request = Acme::Client::CertificateRequest.new(common_name: 'example.org', private_key: test_key)

    expect(request.names).to eq(%w(example.org))
  end

  it 'picks a single domain as the common name' do
    request = Acme::Client::CertificateRequest.new(names: %w(example.org), private_key: test_key)

    expect(request.common_name).to eq('example.org')
    expect(request.subject['CN']).to eq('example.org')
    expect(request.names).to eq(%w(example.org))
  end

  it 'picks the common name from the names' do
    request = Acme::Client::CertificateRequest.new(names: %w(example.org www.example.org), private_key: test_key)

    expect(request.common_name).to eq('example.org')
    expect(request.subject['CN']).to eq('example.org')
    expect(request.names).to eq(%w(example.org www.example.org))
  end

  it 'expects a domain' do
    expect {
      Acme::Client::CertificateRequest.new(private_key: test_key)
    }.to raise_error(ArgumentError, /No common name/)
  end

  it 'disallows arbitrary subject keys' do
    expect {
      Acme::Client::CertificateRequest.new(
        common_name: 'example.org',
        private_key: test_key,
        subject: { :milk => 'yes', 'serialNumber' => 123 }
      )
    }.to raise_error(ArgumentError, /Unexpected subject attributes/)
  end

  it 'checks consistency of given common names' do
    expect {
      Acme::Client::CertificateRequest.new(
        common_name: 'example.org',
        private_key: test_key,
        subject: { common_name: 'example.net' }
      )
    }.to raise_error(ArgumentError, /Conflicting common name/)

    expect {
      Acme::Client::CertificateRequest.new(
        common_name: 'example.org',
        private_key: test_key,
        subject: { 'CN' => 'example.net' }
      )
    }.to raise_error(ArgumentError, /Conflicting common name/)
  end

  it 'assigns the public key' do
    request = Acme::Client::CertificateRequest.new(common_name: 'example.org', private_key: test_key)

    expect(public_key_to_pem(request.csr.public_key)).to eq(public_key_to_pem(test_key))
    expect(request.csr.verify(request.csr.public_key)).to be(true)
  end

  it 'adds the common name to the subject' do
    request = Acme::Client::CertificateRequest.new(common_name: 'example.org', private_key: test_key)

    subject = request.csr.subject.to_a.map { |name, value, _| [name, value] }.to_h
    expect(subject['CN']).to eq('example.org')
  end

  it 'adds other valid attributes to the subject' do
    subject_keys = Acme::Client::CertificateRequest::SUBJECT_KEYS
    subject = subject_keys.each_with_object({}) {|(_, short_name), hash|
      hash[short_name] = 'example'
    }
    request = Acme::Client::CertificateRequest.new(private_key: test_key, subject: subject)

    csr_subject = request.csr.subject.to_a.map { |name, value, _| [name, value] }.to_h
    expect(csr_subject).to eq(subject)
  end

  it 'creates a subjectAltName extension with multiple names' do
    request = Acme::Client::CertificateRequest.new(names: %w(example.org www.example.org), private_key: test_key)

    extension = request.csr.attributes.find { |attribute|
      asn1_dig(attribute).first.value == 'subjectAltName'
    }
    expect(extension).not_to be_nil
    value = asn1_dig(extension).last.value
    expect(value).to include('example.org')
    expect(value).to include('www.example.org')
  end

  it 'signs the request with the private key' do
    request = Acme::Client::CertificateRequest.new(common_name: 'example.org', private_key: test_key)

    expect(verify_csr(request.csr, test_key)).to be(true)
  end

  it 'supports ECDSA keys' do
    ec_key = OpenSSL::PKey::EC.generate('secp384r1')
    request = Acme::Client::CertificateRequest.new(common_name: 'example.org',
                                                   private_key: ec_key)

    expect(request.csr.verify(ec_key)).to be(true)
  end
end