diff --git a/plugins/module_utils/ansible_freeipa_module.py b/plugins/module_utils/ansible_freeipa_module.py
index 4d1a77c37ed7feae8314fefd6b6543ed9f71c169..9bfad7f63ae0616cc69fe2333996cad41326224a 100644
--- a/plugins/module_utils/ansible_freeipa_module.py
+++ b/plugins/module_utils/ansible_freeipa_module.py
@@ -54,6 +54,7 @@ import tempfile
 import shutil
 import socket
 import base64
+import binascii
 import ast
 import time
 from datetime import datetime
@@ -644,6 +645,7 @@ def encode_certificate(cert):
     Encode a certificate using base64.
 
     It also takes FreeIPA and Python versions into account.
+    This is used to convert the certificates returned by find and show.
     """
     if isinstance(cert, (str, unicode, bytes)):
         encoded = base64.b64encode(cert)
@@ -654,6 +656,33 @@ def encode_certificate(cert):
     return encoded
 
 
+def convert_input_certificates(module, certs, state):
+    """
+    Convert certificates.
+
+    Remove all newlines and white spaces from the certificates.
+    This is used on input parameter certificates of modules.
+    """
+    if certs is None:
+        return None
+
+    _certs = []
+    for cert in certs:
+        try:
+            _cert = base64.b64encode(base64.b64decode(cert)).decode("ascii")
+        except (TypeError, binascii.Error) as e:
+            # Idempotency: Do not fail for an invalid cert for state absent.
+            # The invalid certificate can not be set in FreeIPA.
+            if state == "absent":
+                continue
+            module.fail_json(
+                msg="Certificate %s: Base64 decoding failed: %s" %
+                (repr(cert), str(e)))
+        _certs.append(_cert)
+
+    return _certs
+
+
 def load_cert_from_str(cert):
     cert = cert.strip()
     if not cert.startswith("-----BEGIN CERTIFICATE-----"):
diff --git a/plugins/modules/ipahost.py b/plugins/modules/ipahost.py
index 6600d81d09bfae47defc69c87545221a0f846551..24acaa36121100953590cfb4fa11e9a663888897 100644
--- a/plugins/modules/ipahost.py
+++ b/plugins/modules/ipahost.py
@@ -510,7 +510,8 @@ host:
 from ansible.module_utils.ansible_freeipa_module import \
     IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, \
     encode_certificate, is_ipv4_addr, is_ipv6_addr, ipalib_errors, \
-    gen_add_list, gen_intersection_list, normalize_sshpubkey
+    gen_add_list, gen_intersection_list, normalize_sshpubkey, \
+    convert_input_certificates
 from ansible.module_utils import six
 if six.PY3:
     unicode = str
@@ -682,13 +683,6 @@ def check_authind(module, auth_ind):
             "by your IPA version" % "','".join(_invalid))
 
 
-def convert_certificate(certificate):
-    if certificate is None:
-        return None
-
-    return [cert.strip() for cert in certificate]
-
-
 # pylint: disable=unused-argument
 def result_handler(module, result, command, name, args, exit_args,
                    single_host):
@@ -894,7 +888,8 @@ def main():
         auth_ind, requires_pre_auth, ok_as_delegate, ok_to_auth_as_delegate,
         force, reverse, ip_address, update_dns, update_password)
 
-    certificate = convert_certificate(certificate)
+    certificate = convert_input_certificates(ansible_module, certificate,
+                                             state)
 
     if sshpubkey is not None:
         sshpubkey = [str(normalize_sshpubkey(key)) for key in sshpubkey]
@@ -982,7 +977,8 @@ def main():
                     ok_to_auth_as_delegate, force, reverse, ip_address,
                     update_dns, update_password)
 
-                certificate = convert_certificate(certificate)
+                certificate = convert_input_certificates(ansible_module,
+                                                         certificate, state)
 
                 if sshpubkey is not None:
                     sshpubkey = [str(normalize_sshpubkey(key)) for
diff --git a/plugins/modules/ipaidoverrideuser.py b/plugins/modules/ipaidoverrideuser.py
index 6714265f9ea0c8554de0a64027b3c890f29204d7..49412ebd908d660a17eb6a6b9fd20d530acf3e53 100644
--- a/plugins/modules/ipaidoverrideuser.py
+++ b/plugins/modules/ipaidoverrideuser.py
@@ -315,7 +315,7 @@ RETURN = """
 
 from ansible.module_utils.ansible_freeipa_module import \
     IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, gen_add_list, \
-    gen_intersection_list, encode_certificate
+    gen_intersection_list, encode_certificate, convert_input_certificates
 from ansible.module_utils import six
 
 if six.PY3:
@@ -479,8 +479,8 @@ def main():
 
     ansible_module.params_fail_used_invalid(invalid, state, action)
 
-    if certificate is not None:
-        certificate = [cert.strip() for cert in certificate]
+    certificate = convert_input_certificates(ansible_module, certificate,
+                                             state)
 
     # Init
 
diff --git a/plugins/modules/ipaservice.py b/plugins/modules/ipaservice.py
index 6a2e5eb7ad18b36cf59a258c3ce9950fceb58766..c1e9309d88c54079674cda12f02b84fcf383cba8 100644
--- a/plugins/modules/ipaservice.py
+++ b/plugins/modules/ipaservice.py
@@ -378,7 +378,7 @@ RETURN = """
 from ansible.module_utils.ansible_freeipa_module import \
     IPAAnsibleModule, compare_args_ipa, encode_certificate, \
     gen_add_del_lists, gen_add_list, gen_intersection_list, ipalib_errors, \
-    api_get_realm, to_text
+    api_get_realm, to_text, convert_input_certificates
 from ansible.module_utils import six
 if six.PY3:
     unicode = str
@@ -601,12 +601,6 @@ def main():
     # service attributes
     principal = ansible_module.params_get("principal")
     certificate = ansible_module.params_get("certificate")
-    # Any leading or trailing whitespace is removed while adding the
-    # certificate with serive_add_cert. To be able to compare the results
-    # from service_show with the given certificates we have to remove the
-    # white space also.
-    if certificate is not None:
-        certificate = [cert.strip() for cert in certificate]
     pac_type = ansible_module.params_get(
         "pac_type", allow_empty_list_item=True)
     auth_ind = ansible_module.params_get(
@@ -636,6 +630,8 @@ def main():
         ansible_module.fail_json(msg="At least one name or services is "
                                      "required")
     check_parameters(ansible_module, state, action, names)
+    certificate = convert_input_certificates(ansible_module, certificate,
+                                             state)
 
     # Use services if names is None
     if services is not None:
@@ -669,12 +665,8 @@ def main():
                 service_set.add(name)
                 principal = service.get("principal")
                 certificate = service.get("certificate")
-                # Any leading or trailing whitespace is removed while adding
-                # the certificate with serive_add_cert. To be able to compare
-                # the results from service_show with the given certificates
-                # we have to remove the white space also.
-                if certificate is not None:
-                    certificate = [cert.strip() for cert in certificate]
+                certificate = convert_input_certificates(ansible_module,
+                                                         certificate, state)
                 pac_type = service.get("pac_type")
                 auth_ind = service.get("auth_ind")
                 check_authind(ansible_module, auth_ind)
diff --git a/plugins/modules/ipauser.py b/plugins/modules/ipauser.py
index 36372c4adeb2bfeb8e2e6fbc33792eedf68b5709..f78f23ed235ec1395082095c9c3269dc04e7141d 100644
--- a/plugins/modules/ipauser.py
+++ b/plugins/modules/ipauser.py
@@ -741,7 +741,8 @@ user:
 from ansible.module_utils.ansible_freeipa_module import \
     IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, date_format, \
     encode_certificate, load_cert_from_str, DN_x500_text, to_text, \
-    ipalib_errors, gen_add_list, gen_intersection_list
+    ipalib_errors, gen_add_list, gen_intersection_list, \
+    convert_input_certificates
 from ansible.module_utils import six
 if six.PY3:
     unicode = str
@@ -961,13 +962,6 @@ def extend_emails(email, default_email_domain):
     return email
 
 
-def convert_certificate(certificate):
-    if certificate is None:
-        return None
-
-    return [cert.strip() for cert in certificate]
-
-
 def convert_certmapdata(certmapdata):
     if certmapdata is None:
         return None
@@ -1260,7 +1254,8 @@ def main():
             preserve, update_password, smb_logon_script, smb_profile_path,
             smb_home_dir, smb_home_drive, idp, idp_user_id, rename,
         )
-        certificate = convert_certificate(certificate)
+        certificate = convert_input_certificates(ansible_module, certificate,
+                                                 state)
         certmapdata = convert_certmapdata(certmapdata)
 
     # Init
@@ -1371,7 +1366,8 @@ def main():
                     update_password, smb_logon_script, smb_profile_path,
                     smb_home_dir, smb_home_drive, idp, idp_user_id, rename,
                 )
-                certificate = convert_certificate(certificate)
+                certificate = convert_input_certificates(ansible_module,
+                                                         certificate, state)
                 certmapdata = convert_certmapdata(certmapdata)
 
                 # Check API specific parameters