Class: Azure::Certificate

Inherits:
Object
  • Object
show all
Defined in:
lib/azure/certificate.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection) ⇒ Certificate

Returns a new instance of Certificate.



35
36
37
38
# File 'lib/azure/certificate.rb', line 35

def initialize(connection)
  @connection = connection
  @certificate_version = 2 # cf. RFC 5280 - to make it a "v3" certificate
end

Instance Attribute Details

#cert_dataObject

Returns the value of attribute cert_data.



34
35
36
# File 'lib/azure/certificate.rb', line 34

def cert_data
  @cert_data
end

#certificate_versionObject

Returns the value of attribute certificate_version.



34
35
36
# File 'lib/azure/certificate.rb', line 34

def certificate_version
  @certificate_version
end

#connectionObject

Returns the value of attribute connection.



33
34
35
# File 'lib/azure/certificate.rb', line 33

def connection
  @connection
end

#fingerprintObject

Returns the value of attribute fingerprint.



34
35
36
# File 'lib/azure/certificate.rb', line 34

def fingerprint
  @fingerprint
end

Instance Method Details

#create(params) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/azure/certificate.rb', line 39

def create(params)
  # If RSA private key has been specified, then generate an x 509 certificate from the
  # public part of the key
  @cert_data = generate_public_key_certificate_data({:ssh_key => params[:identity_file],
                                         :ssh_key_passphrase => params[:identity_file_passphrase]})
  # Generate XML to call the API
  # Add certificate to the hosted service
  builder = Nokogiri::XML::Builder.new do |xml|
    xml.CertificateFile('xmlns'=>'http://schemas.microsoft.com/windowsazure') {
      xml.Data @cert_data
      xml.CertificateFormat 'pfx'
      xml.Password 'knifeazure'
    }
  end
  # Windows Azure API call
  @connection.query_azure("hostedservices/#{params[:azure_dns_name]}/certificates", "post", builder.to_xml)
  # Return the fingerprint to be used while adding role
  @fingerprint
end

#generate_public_key_certificate_data(params) ⇒ Object



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
# File 'lib/azure/certificate.rb', line 59

def generate_public_key_certificate_data (params)
  # Generate OpenSSL RSA key from the mentioned ssh key path (and passphrase)
  key = OpenSSL::PKey::RSA.new(File.read(params[:ssh_key]), params[:ssh_key_passphrase])
  # Generate X 509 certificate
  ca = OpenSSL::X509::Certificate.new
  ca.version = @certificate_version
  ca.serial = Random.rand(65534) + 1 # 2 digit byte range random number for better security aspect
  ca.subject = OpenSSL::X509::Name.parse "/DC=org/DC=knife-plugin/CN=Opscode CA"
  ca.issuer = ca.subject # root CA's are "self-signed"
  ca.public_key = key.public_key # Assign the ssh-key's public part to the certificate
  ca.not_before = Time.now
  ca.not_after =  ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity
  ef = OpenSSL::X509::ExtensionFactory.new
  ef.subject_certificate = ca
  ef.issuer_certificate = ca
  ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
  ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
  ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
  ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
  ca.sign(key, OpenSSL::Digest::SHA256.new)
  # Generate the SHA1 fingerprint of the der format of the X 509 certificate
  @fingerprint =  OpenSSL::Digest::SHA1.new(ca.to_der)
  # Create the pfx format of the certificate
  pfx = OpenSSL::PKCS12.create('knifeazure', 'knife-azure-pfx',  key,  ca)
  # Encode the pfx format - upload this certificate
  Base64.strict_encode64(pfx.to_der)
end