Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2237)

Unified Diff: net/data/verify_certificate_chain_unittest/openssl_conf.py

Issue 1414393008: Add scripts to generate simple test data for certificate verification. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@key_usages
Patch Set: use __doc__ like a boss Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/data/verify_certificate_chain_unittest/openssl_conf.py
diff --git a/net/data/verify_certificate_chain_unittest/openssl_conf.py b/net/data/verify_certificate_chain_unittest/openssl_conf.py
new file mode 100755
index 0000000000000000000000000000000000000000..6c807393a14d8869ad26dda1358f233fad6ff8c4
--- /dev/null
+++ b/net/data/verify_certificate_chain_unittest/openssl_conf.py
@@ -0,0 +1,136 @@
+#!/usr/bin/python
+# Copyright (c) 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""This file contains helpers for representing, manipulating, and writing
+OpenSSL configuration files [1]
+
+Configuration files are simply a collection of name=value "properties", which
+are grouped into "sections".
+
+[1] https://www.openssl.org/docs/manmaster/apps/config.html
+"""
+
+class Property(object):
+ """Represents a key/value pair in OpenSSL .cnf files.
+
+ Names and values are not quoted in any way, so callers need to pass the text
+ exactly as it should be written to the file (leading and trailing whitespace
+ doesn't matter).
+
+ For instance:
+ baseConstraints = critical, CA:false
+
+ Could be represented by a Property where:
+ name = 'baseConstraints'
+ value = 'critical, CA:false'
+ """
+ def __init__(self, name, value):
+ self.name = name
+ self.value = value
+
+
+ def WriteTo(self, out):
+ """Outputs this property to .cnf file."""
+ out.write('%s = %s\n' % (self.name, self.value))
+
+
+class Section(object):
+ """Represents a section in OpenSSL. For instance:
+ [CA_root]
+ preserve = true
+
+ Could be represented by a Section where:
+ name = 'CA_root'
+ properties = [Property('preserve', 'true')]
+ """
+ def __init__(self, name):
+ self.name = name
+ self.properties = []
+
+
+ def EnsurePropertyNameNotDuplicated(self, name):
+ """Raises an exception of there is more than 1 property named |name|."""
+ count = 0
+ for prop in self.properties:
+ if prop.name == name:
+ count += 1
mattm 2015/11/02 19:40:39 If you want to get into python tricks: count = sum
eroman 2015/11/02 20:51:43 Thanks, I decided not to use that (since I find it
+ if count > 1:
+ raise Exception('Duplicate property: %s' % (name))
+
+
+ def SetProperty(self, name, value):
+ """Replaces, adds, or removes a Property from the Section:
+
+ - If |value| is None, then this is equivalent to calling
+ RemoveProperty(name)
+ - If there is an existing property matching |name| then its value is
+ replaced with |value|
+ - If there are no properties matching |name| then a new one is added at
+ the end of the section
+
+ It is expected that there is AT MOST 1 property with the given name. If
+ that is not the case then this function will raise an error."""
+
+ if value is None:
+ self.RemoveProperty(name)
+ return
+
+ self.EnsurePropertyNameNotDuplicated(name)
+
+ for prop in self.properties:
+ if prop.name == name:
+ prop.value = value
+ return
+
+ self.AddProperty(name, value)
+
+
+ def AddProperty(self, name, value):
+ """Adds a property (allows duplicates)"""
+ self.properties.append(Property(name, value))
+
+
+ def RemoveProperty(self, name):
+ """Removes the property with the indicated name, if it exists.
+
+ It is expected that there is AT MOST 1 property with the given name. If
+ that is not the case then this function will raise an error."""
+ self.EnsurePropertyNameNotDuplicated(name)
+
+ for i in range(len(self.properties)):
+ if self.properties[i].name == name:
+ self.properties.pop(i)
+ return
+
+
+ def WriteTo(self, out):
+ """Outputs the section in the format used by .cnf files"""
+ out.write('[%s]\n' % (self.name))
+ for prop in self.properties:
+ prop.WriteTo(out)
+ out.write('\n')
+
+
+class Config(object):
+ """Represents a .cnf (configuration) file in OpenSSL"""
+ def __init__(self):
+ self.sections = []
+
+
+ def GetSection(self, name):
+ """Gets or creates a section with the given name."""
+ for section in self.sections:
+ if section.name == name:
+ return section
+ new_section = Section(name)
+ self.sections.append(new_section)
+ return new_section
+
+
+ def WriteToFile(self, path):
+ """Outputs the Config to a .cnf files."""
+ with open(path, 'w') as out:
+ for section in self.sections:
+ section.WriteTo(out)

Powered by Google App Engine
This is Rietveld 408576698