github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/certificates.py (about)

     1  from OpenSSL import crypto
     2  import os
     3  from textwrap import dedent
     4  
     5  
     6  def create_certificate(target_dir, ip_address):
     7      """Generate a cert and key file incl. IP SAN for `ip_address`
     8  
     9      Creates a cert.pem and key.pem file signed with a known ca cert.
    10      The generated cert will contain a IP SAN (subject alternative name) that
    11      includes the ip address of the server. This is required for log-forwarding.
    12  
    13      :return: tuple containing generated cert, key filepath pair
    14  
    15      """
    16      ip_address = 'IP:{}'.format(ip_address)
    17  
    18      key = crypto.PKey()
    19      key.generate_key(crypto.TYPE_RSA, 2048)
    20  
    21      csr_contents = generate_csr(target_dir, key, ip_address)
    22      req = crypto.load_certificate_request(crypto.FILETYPE_PEM, csr_contents)
    23  
    24      ca_cert = crypto.load_certificate(
    25          crypto.FILETYPE_PEM, ca_pem_contents)
    26      ca_key = crypto.load_privatekey(
    27          crypto.FILETYPE_PEM, ca_key_pem_contents)
    28  
    29      cert = crypto.X509()
    30      cert.set_version(0x2)
    31      cert.set_subject(req.get_subject())
    32      cert.set_serial_number(1)
    33      cert.gmtime_adj_notBefore(0)
    34      cert.gmtime_adj_notAfter(24 * 60 * 60)
    35      cert.set_issuer(ca_cert.get_subject())
    36      cert.set_pubkey(req.get_pubkey())
    37      cert.add_extensions([
    38          crypto.X509Extension('subjectAltName', False, ip_address),
    39          crypto.X509Extension(
    40              'extendedKeyUsage', False, 'clientAuth, serverAuth'),
    41          crypto.X509Extension(
    42              'keyUsage', True, 'keyEncipherment'),
    43      ])
    44      cert.sign(ca_key, "sha256")
    45  
    46      cert_filepath = os.path.join(target_dir, 'cert.pem')
    47      with open(cert_filepath, 'wt') as f:
    48          f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
    49  
    50      key_filepath = os.path.join(target_dir, 'key.pem')
    51      with open(key_filepath, 'wt') as f:
    52          f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key))
    53  
    54      return (cert_filepath, key_filepath)
    55  
    56  
    57  def generate_csr(target_dir, key, ip_address):
    58      req = crypto.X509Req()
    59      req.set_version(0x2)
    60      req.get_subject().CN = "anyServer"
    61      # Add the IP SAN
    62      req.add_extensions([
    63          crypto.X509Extension("subjectAltName", False, ip_address)
    64      ])
    65      req.set_pubkey(key)
    66      req.sign(key, "sha256")
    67  
    68      return crypto.dump_certificate_request(crypto.FILETYPE_PEM, req)
    69  
    70  
    71  ca_pem_contents = dedent("""\
    72      -----BEGIN CERTIFICATE-----
    73      MIIEFTCCAn2gAwIBAgIBBzANBgkqhkiG9w0BAQsFADAjMRIwEAYDVQQDEwlhbnlT
    74      ZXJ2ZXIxDTALBgNVBAoTBGp1anUwHhcNMTYwNzExMDQyOTM1WhcNMjYwNzA5MDQy
    75      OTM1WjAjMRIwEAYDVQQDEwlhbnlTZXJ2ZXIxDTALBgNVBAoTBGp1anUwggGiMA0G
    76      CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCn6OxY33yAirABoE4UaZJBOnQORIzC
    77      125R71E2TG5gSHjHKA70L0C3dgyWhW9wcyhUbXBuz8Oep2J7kHvzuUPw2AWXI+Y2
    78      c0afWVqfj5kuyUpGhXsqylyf7NDPFs8hwGA6ZCFS3oUAvX8awsVucklxGeZNXZNK
    79      ZFilXKaX1Z3soORmKFZzVfDRqDuofZ2E0tmPh9C5gQ8qswjdBnTrj+0rCnvNekO0
    80      aND6AlkBHU+87pvcax0uUF6PYkXxPikKk1ftCQSII5oB5ksAtRpcZsYl5hT3U/t1
    81      DOA7c35RuIx7ogkcXP9jZ6J2tkmX+GMtUF29KEEnVCht32VDX+C3yS6lbfQB4oDt
    82      Yp3wXRY/LXTW7XTUrhoXB4nkYbw59gis5Cr7zDtUpiWFVYgy/kbxalljSM4N3w2i
    83      dtfxJHYjTfK98124qbCBb4A4ZNBJE2jy//lSIcIMXJv1LXQtTqR4rO1j6TBurohF
    84      NmUYpy3Zv7gn2CkfX6QfNFIj8elKT6dd+RUCAwEAAaNUMFIwDwYDVR0TAQH/BAUw
    85      AwEB/zAPBgNVHREECDAGhwQKwoylMA8GA1UdDwEB/wQFAwMHBAAwHQYDVR0OBBYE
    86      FP+v8GAqHiUCIygXbwWzbUhl/22DMA0GCSqGSIb3DQEBCwUAA4IBgQBVYKeT1O2M
    87      U3OPOy0IwqcA1/64rS1GlRmiw+papmjsy3aru03r8igahnbFd7wQawHaCScXbI/n
    88      OAPT4PDGXn6b71t4uHwWaM8wde159RO3G32N/VfhV6LPRUQunmAZh5QcJK6wWpYu
    89      B1f0dPkU+Q1AfX12oTOX/ld2/o7jaVswHoHoW6K2WQmwzlRQ953J+RJ7jXfrYDKl
    90      OAp3Hb69wAN4Ayc1s92iYUwV5q8UaHQoskHOLWJu964yFBHL8SLe6TLD+Jjv05Mc
    91      Ca7NKq/n25VTDNNaXl5MCNZ048m/GGHfktxxCddaF2grhC5HTUetwkq026PE0Wcq
    92      P+cDrIq6uTA25QqyBYistSa/7z2o0NBi56ySRqxlP2J2TPFZyOb+ZiA4EgYY5no5
    93      u2E+WuKZLVWl7eaQYOHgfYzFf3CvalSBwIjNynRwD/2Ebk7K29GPrIugb3V2+Vwh
    94      rltUXOHUkFGjEHIhr8zixfCxh5OzPJMnJwCZZRYzMO0/0Gw7ll9DmH0=
    95      -----END CERTIFICATE-----
    96      """)
    97  
    98  
    99  ca_key_pem_contents = dedent("""\
   100      -----BEGIN RSA PRIVATE KEY-----
   101      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
   138      -----END RSA PRIVATE KEY-----
   139      """)