| 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..8446e92d476cc3ca07c5dd53e10e492d141383fc | 
| --- /dev/null | 
| +++ b/net/data/verify_certificate_chain_unittest/openssl_conf.py | 
| @@ -0,0 +1,107 @@ | 
| +#!/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 | 
| + | 
| +  Would be 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 | 
| + | 
| +  Is a section named 'CA_root' containing 1 property. | 
| +  """ | 
| +  def __init__(self, name): | 
| +    self.name = name | 
| +    self.properties = [] | 
| + | 
| + | 
| +  def SetProperty(self, name, value): | 
| +    """If value is None then the property is deleted. Otherwise overwrites or | 
| +    adds it""" | 
| +    if value is None: | 
| +      self.RemoveProperty(name) | 
| +      return | 
| + | 
| +    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.""" | 
| +    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) | 
|  |