[Freeipa-devel] [PATCH] 058 Validate and convert certificate SN

Jakub Hrozek jhrozek at redhat.com
Wed Feb 16 14:32:03 UTC 2011


The cert plugin only worked OK with decimal certificate serial numbers.
This patch allows specifying the serial number in hexadecimal, too. The
conversion now works such that:
* with no explicit radix, a best-effort conversion is done using
  int(str, 0) in python. If the format is ambiguous, decimal takes precedence.
* a hexadecimal radix can be specified explicitly using the
  traditional 0x prefix

https://fedorahosted.org/freeipa/ticket/958
https://fedorahosted.org/freeipa/ticket/953

-------------- next part --------------
>From d1a37986652947215422302cc574a321c68a76b5 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Wed, 16 Feb 2011 13:07:13 +0100
Subject: [PATCH] Validate and convert certificate SN

The cert plugin only worked OK with decimal certificate serial numbers.
This patch allows specifying the serial number in hexadecimal, too. The
conversion now works such that:
 * with no explicit radix, a best-effort conversion is done using int(str,
   0) in python. If the format is ambiguous, decimal takes precedence.
 * a hexadecimal radix can be specified explicitly with the traditional
   0x prefix

https://fedorahosted.org/freeipa/ticket/958
https://fedorahosted.org/freeipa/ticket/953
---
 API.txt                |    6 +++---
 ipalib/plugins/cert.py |   28 ++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/API.txt b/API.txt
index 9e34647..4250113 100644
--- a/API.txt
+++ b/API.txt
@@ -303,7 +303,7 @@ output: Output('count', <type 'int'>, Gettext('', domain='ipa', localedir=None))
 output: Output('results', <type 'list'>, Gettext('', domain='ipa', localedir=None))
 command: cert_remove_hold
 args: 1,0,1
-arg: Str('serial_number', label=Gettext('Serial number', domain='ipa', localedir=None))
+arg: Str('serial_number', validate_serial_number, label=Gettext('Serial number', domain='ipa', localedir=None), normalizer=normalize_serial_number)
 output: Output('result', None, None)
 command: cert_request
 args: 1,3,1
@@ -314,12 +314,12 @@ option: Flag('add', autofill=True, default=False,lag('add', autofill=True, defau
 output: Output('result', <type 'dict'>, Gettext('Dictionary mapping variable name to value', domain='ipa', localedir=None))
 command: cert_revoke
 args: 1,1,1
-arg: Str('serial_number', label=Gettext('Serial number', domain='ipa', localedir=None))
+arg: Str('serial_number', validate_serial_number, label=Gettext('Serial number', domain='ipa', localedir=None), normalizer=normalize_serial_number)
 option: Int('revocation_reason?', default=0, label=Gettext('Reason', domain='ipa', localedir=None), maxvalue=10, minvalue=0)
 output: Output('result', None, None)
 command: cert_show
 args: 1,1,1
-arg: Str('serial_number', label=Gettext('Serial number', domain='ipa', localedir=None))
+arg: Str('serial_number', validate_serial_number, label=Gettext('Serial number', domain='ipa', localedir=None), normalizer=normalize_serial_number)
 option: Str('out?', exclude='webui', label=Gettext('Output filename', domain='ipa', localedir=None))
 output: Output('result', None, None)
 command: cert_status
diff --git a/ipalib/plugins/cert.py b/ipalib/plugins/cert.py
index f5ffd15..19e0780 100644
--- a/ipalib/plugins/cert.py
+++ b/ipalib/plugins/cert.py
@@ -141,6 +141,32 @@ def normalize_csr(csr):
 
     return csr
 
+def _convert_serial_number(num):
+    """
+    Convert a SN given in decimal or hexadecimal.
+    Returns the number or None if conversion fails.
+    """
+    # plain decimal or hexa with radix prefix
+    try:
+        num = int(num, 0)
+    except ValueError:
+        try:
+            # hexa without prefix
+            num = int(num, 16)
+        except ValueError:
+            num = None
+
+    return num
+
+def validate_serial_number(ugettext, num):
+    if _convert_serial_number(num) == None:
+        return u"Decimal or hexadecimal number is required for serial number"
+    return None
+
+def normalize_serial_number(num):
+    # It's been already validated
+    return unicode(_convert_serial_number(num))
+
 def get_host_from_principal(principal):
     """
     Given a principal with or without a realm return the
@@ -378,8 +404,10 @@ api.register(cert_status)
 
 
 _serial_number = Str('serial_number',
+    validate_serial_number,
     label=_('Serial number'),
     doc=_('Serial number in decimal or if prefixed with 0x in hexadecimal'),
+    normalizer=normalize_serial_number,
 )
 
 class cert_show(VirtualCommand):
-- 
1.7.4



More information about the Freeipa-devel mailing list