The Extended Validation internal Logistics Bot (EViL-bot)
About the server
The root store server is used to generate the files hosted by the certs.opera.com server.
These files contain information about which Certificate Autority certificates are authorized
as "pre-embedded" in Opera, as well as associated information, such as Extended Validation
information and certificates that are to be deleted or marked untrusted.
To reduce the footprint of Opera's executable, as well as to increase the flexibility of
Opera's rootstore and reduce the delay between accepting a root and when it becomes available
to users, and need to ship new version with the new root(s), most of the roots are now (2008)
to be hosted in a central repository, certs.opera.com
To reduce the attack surface for the system, it has the following attributes:
- All files being distributed are digitally signed by a RSA key that is at least 4096 bits long.
This key should be at least as strong as the keys of the certificates it is signing. A client must
not accept a file from this system that does not verify.
- TODO: Use Elliptic Curves Cryptography for the signtaure instead of RSA, as these will reduce the file footprint,
as well as the CPU cost of signing and verifying the files.
- Rationale: We must do our best to prevent tampering with the files after they have been produced, and
we need to protect ourselves against the possibility that the public servers are compromised.
- The server will only be hosted on a TLS 1.0 (or later) server, using a 2048 bit RSA certificate, issued off
a recognized EV root.
- TODO: Use Authenticated only ciphers for the TLS communication.
- Rationale:
Using a TLS server prevents replay attacks of old, but still valid files. Using an EV certificate is "necessary"
because the server will host our information about authorized EV roots. Using Authenticated-only ciphers will
increase the transparency of the data transfer, and as there is no sensitive data being transferred, encryption
is not really needed, only authentication (it may also slightly reduce the CPU cost)
- The production of the files should be performed on a server that is as separated from the network as
is practically possible
- Rationale: To be able to update the files automatically, the production
server must have direct unencrypted access to the signing keys; to reduce the likelyhood of a compromise
of this server it must be as separated as possible from the network, even an intranet. While a physically
and networkwise isolated machine would be ideal, this introduces a manual step into the process. A compromise
solution is then to have a non-Ethernet connection, e.g. a serial cable, between the production server and
a networked backend that forwards the files to the public servers.
- The files must only be valid for a certain period of time, preferably 2-4 weeks, but less than 6 months,
and clients must not accept files that are not valid.
- Rationale: A limited validity period reduces the possibility of replay attacks, e.g. through compromised
TLS filtering proxies.
- The list of EV-oids must only be valid for a certain period of time, preferably 2-4 weeks, but less than 6 months,
and less than the validity of the files, and clients must not accept files that are not valid. The validity period must
also not extend past the date at which the CA will loose the EV status, and must be reduced to an absolute minimum during
a grace period.
- Rationale: A limited validity period reduces the possibility of replay attacks, e.g. through compromised
TLS filtering proxies. EV OIDs are only valid for a limited period, depending on the result of an EV audit. Once the
CA moves out of this period, they enter a grace period where the get some time to get back in compliance, but during
this period information may become available that makes it necessary to remove the OIDs.
The above countermeasures are unable to counter these threats, and separate countermeasures
that are out of scope for this document must be taken to counter them:
- Compromised Opera executable where the signature check has been disabled
- Compromised CVS respository
- Renegade developers with CVS access
- Renedade employees with physical access the to the production server(s)
- Intruders that gain physical access to the production server(s)
The current system is organized as follows:
- A production server (the "backmost"-end) that produces and signs the files. This
process is repeated every 6 hours.
- A backend that fetches the produced files from the "backmost"-end and forwards them
to the public servers
- One or more public frontends, secured with TLS using 2048 bit RSA key. This part
of the system must have enough capacity to serve all opera users at least once a
week
- The Opera installation is coded to only open a single connection at a time to the
frontends to reduce load on the server.
Features of the system
- A repository indexfile, listing all certificate files
- An entry for a certificate may indicate that the certificate must be updated
- An entry for a certficate may also indicate that another particular certificate
is required when that certificate is installed. This is particularly useful to push
EV releated roots, which are cross-signed by another root to make the chain acceptable
to clients without the new root.
- The index may contain a list of certificates to be deleted.
- The index may contain a list of certficates that are untrusted and should be added
to the list of untrusted certificates.
- Each certificate file will contain the data for one or more certificates, data includes
name, the certificate and eventual EV information. If multiple certificates are
included they are either certificates that have the same ID, or certificates that
must be installed at the same time, due to the fact that they are either intermediates
or associated EV roots.
- A list of roots that are authorized for EV, including the recogniozed EV-OIDs
Certificate IDs
A Certificate ID consists of a version number followed by the SHA-256 digest of
identifying data from a certificate. Two or more different certificate IDs exist for each certificate:
- Just the subject name (The client uses the issuer name)
- The subject name and the public key
- The subject name and an Authority key identifier.
This variation allows multiple ways of finding a certificate, depending on what
data is available, e.g if the root is not available, the only thing you know is
the issuer name and maybe the Authority Key Identifier. Just the subject name is
not usually enough, as it is possible (but not recommended) that a certificate have
the same name as another, and only the public keys are different.
The version number may be one byte or longer. The current version number is 0x01.
The version number identifies major changes in the fileformat and the signing key.
any given version of Opera can only recognize and retrieve a single version.
In filenames the Certificate ID is encoded in hexadecimal for with the version number
hexencoded (uppercase letters) as a single block, followed immediately (without
any spacing characters) by the SHA-256 digest result coded in blocks of two bytes
(four hexadecimal digits) separated by "_" (underscore), and with ".xml" as the
extension. E.g. 010203_0405_0607_0809_0A0B_0C0D_0E0F_1011_1213_1415_1617_1819_1A1B_1C1D_1E1F_2021.xml
Version numbers
- 0x01
- Debug version, not to be used by final version, but may be used by Technology Preview
and Alpha versions. Once a new version has been defined, this version must not be
hosted on the public servers. The signing key is a 4096 bit RSA key stored in the
rootstore module in the CVS repository. Signatures are encoded using PKCS #1.5
Fileformats
General syntax
Each file consists of the xml header, verbatim as below, with the specified <LF>s
<?xml version="1.0" encoding="utf-8" ?><LF>
<!-- [base64-encoded signature]<LF>
-->
[XML content as specfied for each file]
- The first line and the comment-start tag MUST be present at the start of the file, exactly as outlined above.
- The signature MUST be contained on a single line.
- Content starting the line following the signature (after the LF), including the
comment end tag, are included in the calculation of the signature.
- Textitems and values are always the first item after the start tag, and other content
that is not contained in a subelement will be ignored.
- TODO: Add expiration info to signature.
repository.xml
- Location and name
- /<version>/repository.xml
- Structure
-
<repository>
<repository-item>[KeyID Hexadecimal form]
<update-item>[Expiration date ASN1 UTC Time or Generalized Time]</update-item>
<required-item>[KeyID Hexadecimal form]</required-item>
</repository-item>
<delete-list>
<delete-item>[KeyID Hexadecimal form]
<delete-reason>[Human readable explanation for the deletion]</delete-reason>
</delete-item>
</delete-list>
<untrusted-list>
<untrusted-item>[KeyID Hexadecimal form]
<untrusted-reason>[Human readable explanation for the deletion]</untrusted-reason>
</untrusted-item>
</untrusted-list>
</repository>
- repository
- Outer wrapper. Contains repository-item, delete-list
and untrusted-list
- repository-items
- Specifies the ID of a repository item. May also contain update-item and required-item objects.
- update-item
- This certificate should be updated if the client have an old version of it. The value
of the field specifies the expiration date of the new certificate, as a copy of the xpiration field from the certificate
(ASN.1 UTC or generalize time records). If the expiration date of the certificate stored by the client is earlier than
this date, the client should update it by downloading the identified certficate.
- required-item
- The value of this record is the ID of a certificate that the client SHOULD have if it has the
certificate identified by the containing record. If it does not have the certificate identified by this record it should download it.
- delete-list
- Optional list of certificates that should be removed from the repository of an instance.
Each designate is indicated by the delete-item id. Deletion will only be
done if the certificate is "pre-shipped". This option SHOULD be used sparingly,
and only when users are in grave danger of being tricked by the use of such a certificate,
and in such cases the certificate should also be added to the untrusted list. A
possible second use is if a root was added to the repository by mistake.
- delete-item
- The certificate identified by this ID should be deleted if it was "pre-shipped". The
restriction to pre-shipped is due to the fact that users may install roots they
have authorized themselves; in such cases the user assumes responsibility for their
own actions. TODO: Implement restriction.
- delete-reason
- A short explanation of why the certificate is being deleted.
- untrusted-list
- Optional list of certificates that are to be added to the Untrusted certificate store in the instance.
Each such certificate is designated by an untrusted-item record, and if
the client does not have a certificate with the given ID in its untrusted
store, it should download the certificate and add it to the store. Files for these
certificates are located in the <version>/untrusted/ directory.
- untrusted-item
- The certificate identified by this ID should be added to the untrusted certificate store in the client if it is not already there.
- untrusted-reason
- This is a short explanation of why the certifiate is not trusted, and should be automatically blocked by clients.
Certificate fields
This subsection details the fields that can be used to represent a certificate and associated data.
- Location
- Inside a certificate encapsulating tag of a certificate file. See specific files.
- Format
<issuer>[text]</issuer>
<shortname>[Text]</shortname>
<certificate-data>[Base64 encoded data]</certificate-data>
<ev-oid-text>
<ev-oid-entry>[Object ID in numerical text form</ev-oid-entry>
</ev-oid-text>
<ev-oids>[Base64 encoded data]</ev-oids>
- issuer
- This field contains the issuers name in a one-line format, e.g. "/C=JP/O=SECOM
Trust.net/OU=Security Communication RootCA1", generated from the subject field of
the certficate.
- shortname
- This optional field is a friendly name that
can be used to identify the certificate in the UI if the default name is too long
or not good enough.
- certificate-data
- This field contains the Base64
encoded binary data of the certificate. Whitespace to break the date into multiple
lines is permitted, and encouraged.
- ev-oid-text
- This is an optional
list of the EV OIDs recognized for the certificate. It may contain one or more ev-oid-entry
fields. The data are intended for human readers, to explain what is in the ev-oids
field.
- ev-oid-entry
- This field contain a single EV Object ID (OID) displayed
in the ASCII numerical form.
- ev-oids
- This field contains a sequence of EV-OIDs in DER format, followed by one or more signatures of the EV-OID sequence
encapsulated in OCTET STRING objects. At least one signature must be generated by
the key used to sign the containing file. TODO:
Add expiration data.
Certificate files
- Location
- Inside a file in the /<version>/roots folder of the repository.
- Format
<certificates>
<certificate>
[Any Certificate fields]
</certificate>
</certificates>
- certificates
- This is the wrapper of one or more certificates, each
indicated by a certificate tag.
- certificate
- This field contains
a single certificate, as described in the certificate fields section. Any field
may be used, but the sequence MUST contain at least the certificate-data
tag. When processing this field the client must decode the certificate-data fields,
and add it, optionally overriding an older version of the certificate, and register
it in the appropriate authority or intermediate CA store with the shortname, warn
and deny flags (if any). If there are any EV OIDs supporting clients must register
them, provided they are valid, and remove registered EV OIDs if there are none in
this list.
Untrusted certificate files
- Location
-
Inside a file in the /<version>/untrusted folder of the repository.
- Format
-
<untrusted-certificate>
<subject>[text]</subject>
<shortname>[Text]</shortname>
<untrusted_reason>[Text]</untrusted_reason>
<certificate-data>[Base64 encoded data]</certificate-data>
</untrusted-certificate>
- untrusted-certificate
- This field contains a single
certificate, as described in the certificate fields section. Only the subject, shortname,
untrusted-reason and certificate-data field be used,
but the sequence MUST contain at least the certificate-data tag. When processing
this field the client must decode the certificate-data fields, and add it to the untrusted
store, optionally overriding an older version of the certificate, with the specified
shortname in the entry. Some of these fields are explained in the certificate fields
section above.
- subject
- This field contains the issuers name in a one-line
format, e.g. "/C=JP/O=SECOM Trust.net/OU=Security Communication RootCA1", generated
from the subject field of the certficate. The reason it is called subject in this
file, and issuer in the other is that trusted certificate is always an issuer, while
in this case we are always dealing with a certificate issued to a subject.
- untrusted-reason
- This
is a short explanation for why the certificate is not trusted. The shortname should
contain an even shorter version of this.
EV-OID file files
- Location
-
/<version>/ev-oids.xml
- Format
-
<ev-oid-list>
<issuer>
<issuer-name> [text] </issuer-name>
<issuer-id> [Base64 encoded subject name] </issuer-id>
<issuer-key> [Base64 encoded SHA-1 hash of certificate's public key] </issuer-key>
<ev-oid-text>
<ev-oid-entry>[Object ID in numerical text form</ev-oid-entry>
</ev-oid-text>
<ev-oids>[Base64 encoded data]</ev-oids>
</issuer>
</ev-oid-list>
- ev-oid-list
- This contains a list of issuers, each containing the
EV specification for one root certificate.
- issuer
- This contains the
data needed to identify the root, and the EV-OIDs associated with the root. When
reading this field the client must locate the root certificate with the given issuer-id
(subject name) and a public key that matches the issuer-key hash-id, and add the
associated EV OIDs to the entry. If a root prevsiously had EV OIDs associated with
it but does not have in the current version, the OIDs must be removed. The definition
of ev-oid-text and ev-oids is the same as in the above certificate fields defintions.
- issuer-name
- This field contains the issuers name in a one-line
format, e.g. "/C=JP/O=SECOM Trust.net/OU=Security Communication RootCA1", generated
from the subject field of the certficate.
- issuer-id
- This is a Base64
encoding of the root certificate's subject name. This must be, together with the
issuer-key field, a complete match with the certificate to be associated with OIDs.
- issuer-key
- This
is a Base64 encoding of the SHA-1 digest of the certificate's public key. TODO:
Change to using SHA-256?
File Generator system
The backmost-end, an almost isolated machine, runs a program called .... "program"
build the files in the repository. Prior to being run all files and directories
in the output directory must be deleted. After the program has run the content in
the output directory is copied to the public servers.
The generator program uses OpenSSL to perform the cryptographic operations, as well
as many of the IO operations.
The generators flow is as follows:
- The output folders are created
- The signing keys are loaded
- An internal list of the certificates, and which files they are to be written
to is created.
- The repository index is written to a memory file for signing
- For each item in the index a certificate file is created, signed and saved to disk
- If there are any "delete" items, they are written to the repository index next
- Last, all the Untrusted items are written to the repository index, and certificate
files for each added. TODO: what about duplicates?
- Then each root that have been authorized for EV is listed in the EV-OIDs list.
In case of an error, the application will exit with an error code.