def test_rekey_keytype_DSA(self, request_cert): """Test certmonger rekey command works fine Test is to check if -G (keytype) with DSA fails related: https://bugzilla.redhat.com/show_bug.cgi?id=1249165 """ # rekey with RSA key type self.master.run_command([ 'getcert', 'rekey', '-i', self.request_id, '-g', '3072', '-G', 'DSA' ]) status = tasks.wait_for_request(self.master, self.request_id, 100) assert status == "CA_UNREACHABLE" # grep will return file name req_file = self.master.run_command([ "grep", "-rl", f"id={self.request_id}", paths.CERTMONGER_REQUESTS_DIR ]).stdout_text.strip('\n') # look for keytpe as DSA in request file self.master.run_command(['grep', 'DSA', req_file]) err_msg = 'Unable to create enrollment request: Invalid Request' result = self.master.run_command( ['getcert', 'list', '-i', self.request_id]) assert err_msg in result.stdout_text
def test_cacert_file_appear_with_option_F(self): """Test if getcert creates cacert file with -F option It took longer to create the cacert file in older version. restarting the certmonger service creates the file at the location specified by -F option. This fix is to check that cacert file creates immediately after certificate goes into MONITORING state. related: https://pagure.io/freeipa/issue/8105 """ cmd_arg = [ "ipa-getcert", "request", "-f", os.path.join(paths.OPENSSL_CERTS_DIR, "test.pem"), "-k", os.path.join(paths.OPENSSL_PRIVATE_DIR, "test.key"), "-K", "test/%s" % self.clients[0].hostname, "-F", os.path.join(paths.OPENSSL_DIR, "test.CA"), ] result = self.clients[0].run_command(cmd_arg) request_id = re.findall(r'\d+', result.stdout_text) # check if certificate is in MONITORING state status = tasks.wait_for_request(self.clients[0], request_id[0], 50) assert status == "MONITORING" self.clients[0].run_command( ["ls", "-l", os.path.join(paths.OPENSSL_DIR, "test.CA")])
def test_certmonger_rekey_keysize(self, request_cert): """Test certmonger rekey command works fine Certmonger's rekey command was throwing an error as unrecognized command. Test is to check if -g (keysize) option is working fine. related: https://bugzilla.redhat.com/show_bug.cgi?id=1249165 """ certdata = self.master.get_file_contents( os.path.join(paths.OPENSSL_CERTS_DIR, f"{self.request_id}.pem")) cert = x509.load_pem_x509_certificate(certdata, default_backend()) assert cert.public_key().key_size == 2048 # rekey with key size 3072 self.master.run_command( ['getcert', 'rekey', '-i', self.request_id, '-g', '3072']) status = tasks.wait_for_request(self.master, self.request_id, 100) assert status == "MONITORING" certdata = self.master.get_file_contents( os.path.join(paths.OPENSSL_CERTS_DIR, f"{self.request_id}.pem")) cert = x509.load_pem_x509_certificate(certdata, default_backend()) # check if rekey command updated the key size assert cert.public_key().key_size == 3072
def test_rekey_keytype_DSA(self): """Test certmonger rekey command works fine Test is to check if -G (keytype) with DSA fails related: https://bugzilla.redhat.com/show_bug.cgi?id=1249165 """ result = self.master.run_command([ 'ipa-getcert', 'request', '-f', os.path.join(paths.OPENSSL_CERTS_DIR, "test_dsa.pem"), '-k', os.path.join(paths.OPENSSL_PRIVATE_DIR, "test_dsa.key"), '-K', 'test/{}'.format(self.master.hostname), ]) req_id = re.findall(r'\d+', result.stdout_text) status = tasks.wait_for_request(self.master, req_id[0], 100) assert status == "MONITORING" # rekey with RSA key type self.master.run_command( ['getcert', 'rekey', '-i', req_id[0], '-g', '3072', '-G', 'DSA']) time.sleep(100) # look for keytpe as DSA in request file self.master.run_command([ 'grep', 'DSA', os.path.join(paths.CERTMONGER_REQUESTS_DIR, req_id[0]), ]) err_msg = 'Unable to create enrollment request: Invalid Request' result = self.master.run_command(['getcert', 'list', '-i', req_id[0]]) assert err_msg in result.stdout_text
def request_cert(self): """Fixture to request and remove a certificate""" self.request_id = ''.join( random.choice(string.ascii_lowercase) for i in range(10)) self.master.run_command([ 'ipa-getcert', 'request', '-f', os.path.join( paths.OPENSSL_CERTS_DIR, f"{self.request_id}.pem", ), '-k', os.path.join(paths.OPENSSL_PRIVATE_DIR, f"{self.request_id}.key"), '-I', self.request_id, '-K', 'test/{}'.format(self.master.hostname) ]) status = tasks.wait_for_request(self.master, self.request_id, 100) assert status == "MONITORING" yield self.master.run_command( ['getcert', 'stop-tracking', '-i', self.request_id]) self.master.run_command([ "rm", "-rf", os.path.join(paths.OPENSSL_CERTS_DIR, f"{self.request_id}.pem"), ]) self.master.run_command([ "rm", "-rf", os.path.join(paths.OPENSSL_PRIVATE_DIR, f"{self.request_id}.key"), ])
def test_rekey_keytype_DSA(self): """Test certmonger rekey command works fine Test is to check if -G (keytype) with DSA fails related: https://bugzilla.redhat.com/show_bug.cgi?id=1249165 """ result = self.master.run_command([ 'ipa-getcert', 'request', '-f', '/etc/pki/tls/certs/test_dsa.pem', '-k', '/etc/pki/tls/private/test_dsa.key', '-K', 'test/{}'.format(self.master.hostname)]) req_id = re.findall(r'\d+', result.stdout_text) status = tasks.wait_for_request(self.master, req_id[0], 100) assert status == "MONITORING" # rekey with RSA key type self.master.run_command(['getcert', 'rekey', '-i', req_id[0], '-g', '3072', '-G', 'DSA']) time.sleep(100) # look for keytpe as DSA in request file self.master.run_command([ 'grep', 'DSA', '/var/lib/certmonger/requests/{}'.format(req_id[0]) ]) err_msg = 'Unable to create enrollment request: Invalid Request' result = self.master.run_command(['getcert', 'list', '-i', req_id[0]]) assert err_msg in result.stdout_text
def request_cert(self): """Fixture to request and remove a certificate""" self.request_id = ''.join( random.choice( string.ascii_lowercase ) for i in range(10) ) self.master.run_command([ 'ipa-getcert', 'request', '-f', '/etc/pki/tls/certs/{}.pem'.format(self.request_id), '-k', '/etc/pki/tls/private/{}.key'.format(self.request_id), '-I', self.request_id, '-K', 'test/{}'.format(self.master.hostname)]) status = tasks.wait_for_request(self.master, self.request_id, 100) assert status == "MONITORING" yield self.master.run_command(['getcert', 'stop-tracking', '-i', self.request_id]) self.master.run_command( [ 'rm', '-rf', '/etc/pki/tls/certs/{}.pem'.format(self.request_id) ] ) self.master.run_command( [ 'rm', '-rf', '/etc/pki/tls/private/{}.key'.format(self.request_id) ] )
def test_ipa_getcert_san_aci(self): """Test for DNS and IP SAN extensions + ACIs """ hostname = self.clients[0].hostname certfile = os.path.join(paths.OPENSSL_CERTS_DIR, "test2.pem") tasks.kinit_admin(self.master) zone = tasks.prepare_reverse_zone(self.master, self.clients[0].ip)[0] # add PTR dns record for cert request with SAN extention rec = str(self.clients[0].ip).split('.')[3] result = self.master.run_command( ['ipa', 'dnsrecord-add', zone, rec, '--ptr-rec', hostname]) assert 'Record name: {}'.format(rec) in result.stdout_text assert 'PTR record: {}'.format(hostname) in result.stdout_text name, zone = hostname.split('.', 1) self.master.run_command(['ipa', 'dnsrecord-show', zone, name]) tasks.kdestroy_all(self.master) cmd_arg = [ 'ipa-getcert', 'request', '-v', '-w', '-f', certfile, '-k', os.path.join(paths.OPENSSL_PRIVATE_DIR, "test2.key"), '-K', f'test/{hostname}', '-D', hostname, '-A', self.clients[0].ip, ] result = self.clients[0].run_command(cmd_arg) request_id = re.findall(r'\d+', result.stdout_text) # check if certificate is in MONITORING state status = tasks.wait_for_request(self.clients[0], request_id[0], 50) assert status == "MONITORING" certdata = self.clients[0].get_file_contents(certfile) cert = x509.load_pem_x509_certificate(certdata, default_backend()) ext = cert.extensions.get_extension_for_oid( ExtensionOID.SUBJECT_ALTERNATIVE_NAME) dnsnames = ext.value.get_values_for_type(x509.DNSName) assert dnsnames == [self.clients[0].hostname] ipaddrs = ext.value.get_values_for_type(x509.IPAddress) assert ipaddrs == [ipaddress.ip_address(self.clients[0].ip)]
def test_rekey_keytype_RSA(self, request_cert): """Test certmonger rekey command works fine Certmonger's rekey command was throwing an error as unrecognized command. Test is to check if -G (keytype) option is working fine. Currently only RSA type is supported related: https://bugzilla.redhat.com/show_bug.cgi?id=1249165 """ # rekey with RSA key type self.master.run_command([ 'getcert', 'rekey', '-i', self.request_id, '-g', '3072', '-G', 'RSA' ]) status = tasks.wait_for_request(self.master, self.request_id, 100) assert status == "MONITORING"
def test_getcert_list_profile_using_subca(self, test_subca_certs): """ Test that getcert list command displays the profile for the cert requests generated, with a SubCA configured on the IPA server. """ cmd_arg = [ "getcert", "request", "-c", "ipa", "-I", "test-request", "-k", "/etc/pki/tls/private/test.key", "-f", "/etc/pki/tls/certs/test.pem", "-D", self.master.hostname, "-K", "host/%s" % self.master.hostname, "-N", "CN={}".format(self.master.hostname), "-U", "id-kp-clientAuth", "-X", "mysubca", "-T", "caIPAserviceCert", ] result = self.master.run_command(cmd_arg) assert ( 'New signing request "test-request" added.\n' in result.stdout_text ) status = tasks.wait_for_request(self.master, "test-request", 300) if status == "MONITORING": result = self.master.run_command( ["getcert", "list", "-i", "test-request"] ) assert "profile: caIPAserviceCert" in result.stdout_text else: raise AssertionError("certmonger request is " "in state {}". format(status))
def test_ipa_getcert_san_aci(self): """Test for DNS and IP SAN extensions + ACIs """ hostname = self.clients[0].hostname certfile = '/etc/pki/tls/certs/test2.pem' tasks.kinit_admin(self.master) name, zone = hostname.split('.', 1) self.master.run_command(['ipa', 'dnsrecord-show', zone, name]) tasks.kdestroy_all(self.master) cmd_arg = [ 'ipa-getcert', 'request', '-v', '-w', '-f', certfile, '-k', '/etc/pki/tls/private/test2.key', '-K', f'test/{hostname}', '-D', hostname, '-A', self.clients[0].ip, ] result = self.clients[0].run_command(cmd_arg) request_id = re.findall(r'\d+', result.stdout_text) # check if certificate is in MONITORING state status = tasks.wait_for_request(self.clients[0], request_id[0], 50) assert status == "MONITORING" certdata = self.clients[0].get_file_contents(certfile) cert = x509.load_pem_x509_certificate(certdata, default_backend()) ext = cert.extensions.get_extension_for_oid( ExtensionOID.SUBJECT_ALTERNATIVE_NAME) dnsnames = ext.value.get_values_for_type(x509.DNSName) assert dnsnames == [self.clients[0].hostname] ipaddrs = ext.value.get_values_for_type(x509.IPAddress) assert ipaddrs == [ipaddress.ip_address(self.clients[0].ip)]
def test_cacert_file_appear_with_option_F(self): """Test if getcert creates cacert file with -F option It took longer to create the cacert file in older version. restarting the certmonger service creates the file at the location specified by -F option. This fix is to check that cacert file creates immediately after certificate goes into MONITORING state. related: https://pagure.io/freeipa/issue/8105 """ cmd_arg = ['ipa-getcert', 'request', '-f', '/etc/pki/tls/certs/test.pem', '-k', '/etc/pki/tls/private/test.key', '-K', 'test/%s' % self.clients[0].hostname, '-F', '/etc/pki/tls/test.CA'] result = self.clients[0].run_command(cmd_arg) request_id = re.findall(r'\d+', result.stdout_text) # check if certificate is in MONITORING state status = tasks.wait_for_request(self.clients[0], request_id[0], 50) assert status == "MONITORING" self.clients[0].run_command(['ls', '-l', '/etc/pki/tls/test.CA'])
def test_certmonger_reads_token_HSM(self): """Test if certmonger reads the token in HSM This is to ensure added HSM support for FreeIPA. This test adds certificate with sofhsm token and checks if certmonger is tracking it. related : https://pagure.io/certmonger/issue/125 """ test_service = 'test/%s' % self.master.hostname pkcs_passwd = 'Secret123' pin = '123456' noisefile = '/tmp/noisefile' self.master.put_file_contents(noisefile, os.urandom(64)) tasks.kinit_admin(self.master) tasks.install_dns(self.master) self.master.run_command(['ipa', 'service-add', test_service]) # create a csr cmd_args = ['certutil', '-d', paths.NSS_DB_DIR, '-R', '-a', '-o', '/root/ipa.csr', '-s', "CN=%s" % self.master.hostname, '-z', noisefile] self.master.run_command(cmd_args) # request certificate cmd_args = ['ipa', 'cert-request', '--principal', test_service, '--certificate-out', '/root/test.pem', '/root/ipa.csr'] self.master.run_command(cmd_args) # adding trust flag cmd_args = ['certutil', '-A', '-d', paths.NSS_DB_DIR, '-n', 'test', '-a', '-i', '/root/test.pem', '-t', 'u,u,u'] self.master.run_command(cmd_args) # export pkcs12 file cmd_args = ['pk12util', '-o', '/root/test.p12', '-d', paths.NSS_DB_DIR, '-n', 'test', '-W', pkcs_passwd] self.master.run_command(cmd_args) # add softhsm lib cmd_args = ['modutil', '-dbdir', paths.NSS_DB_DIR, '-add', 'softhsm', '-libfile', '/usr/lib64/softhsm/libsofthsm.so'] self.master.run_command(cmd_args, stdin_text="\n\n") # create a token cmd_args = ['softhsm2-util', '--init-token', '--label', 'test', '--pin', pin, '--so-pin', pin, '--free'] self.master.run_command(cmd_args) self.master.run_command(['softhsm2-util', '--show-slots']) cmd_args = ['certutil', '-F', '-d', paths.NSS_DB_DIR, '-n', 'test'] self.master.run_command(cmd_args) cmd_args = ['pk12util', '-i', '/root/test.p12', '-d', paths.NSS_DB_DIR, '-h', 'test', '-W', pkcs_passwd, '-K', pin] self.master.run_command(cmd_args) cmd_args = ['certutil', '-A', '-d', paths.NSS_DB_DIR, '-n', 'IPA CA', '-t', 'CT,,', '-a', '-i', paths.IPA_CA_CRT] self.master.run_command(cmd_args) # validate the certificate self.master.put_file_contents('/root/pinfile', pin) cmd_args = ['certutil', '-V', '-u', 'V', '-e', '-d', paths.NSS_DB_DIR, '-h', 'test', '-n', 'test:test', '-f', '/root/pinfile'] result = self.master.run_command(cmd_args) assert 'certificate is valid' in result.stdout_text # add certificate tracking to certmonger cmd_args = ['ipa-getcert', 'start-tracking', '-d', paths.NSS_DB_DIR, '-n', 'test', '-t', 'test', '-P', pin, '-K', test_service] result = self.master.run_command(cmd_args) request_id = re.findall(r'\d+', result.stdout_text) # check if certificate is tracked by certmonger status = tasks.wait_for_request(self.master, request_id[0], 300) assert status == "MONITORING" # ensure if key and token are re-usable cmd_args = ['getcert', 'resubmit', '-i', request_id[0]] self.master.run_command(cmd_args) status = tasks.wait_for_request(self.master, request_id[0], 300) assert status == "MONITORING"
def test_certmonger_empty_cert_not_segfault(self): """Test empty cert request doesn't force certmonger to segfault Test scenario: create a cert request file in /var/lib/certmonger/requests which is missing most of the required information, and ask request a new certificate to certmonger. The wrong request file should not make certmonger crash. related: https://pagure.io/certmonger/issue/191 """ empty_cert_req_content = textwrap.dedent(""" id=dogtag-ipa-renew-agent key_type=UNSPECIFIED key_gen_type=UNSPECIFIED key_size=0 key_gen_size=0 key_next_type=UNSPECIFIED key_next_gen_type=UNSPECIFIED key_next_size=0 key_next_gen_size=0 key_preserve=0 key_storage_type=NONE key_perms=0 key_requested_count=0 key_issued_count=0 cert_storage_type=FILE cert_perms=0 cert_is_ca=0 cert_ca_path_length=0 cert_no_ocsp_check=0 last_need_notify_check=19700101000000 last_need_enroll_check=19700101000000 template_is_ca=0 template_ca_path_length=-1 template_no_ocsp_check=0 state=NEED_KEY_PAIR autorenew=0 monitor=0 submitted=19700101000000 """) # stop certmonger service self.master.run_command(['systemctl', 'stop', 'certmonger']) # place an empty cert request file to certmonger request dir self.master.put_file_contents( os.path.join(paths.CERTMONGER_REQUESTS_DIR, '20211125062617'), empty_cert_req_content ) # start certmonger, it should not fail self.master.run_command(['systemctl', 'start', 'certmonger']) # request a new cert, should succeed and certmonger doesn't goes # to segfault result = self.master.run_command([ "ipa-getcert", "request", "-f", os.path.join(paths.OPENSSL_CERTS_DIR, "test.pem"), "-k", os.path.join(paths.OPENSSL_PRIVATE_DIR, "test.key"), ]) request_id = re.findall(r'\d+', result.stdout_text) # check if certificate is in MONITORING state status = tasks.wait_for_request(self.master, request_id[0], 50) assert status == "MONITORING" self.master.run_command( ['ipa-getcert', 'stop-tracking', '-i', request_id[0]] ) self.master.run_command([ 'rm', '-rf', os.path.join(paths.CERTMONGER_REQUESTS_DIR, '20211125062617'), os.path.join(paths.OPENSSL_CERTS_DIR, 'test.pem'), os.path.join(paths.OPENSSL_PRIVATE_DIR, 'test.key') ])