<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">
<chapter>
<header>
<copyright>
<year>2008</year>
<year>2013</year>
<holder>Ericsson AB, All Rights Reserved</holder>
</copyright>
<legalnotice>
The contents of this file are subject to the Erlang Public License,
Version 1.1, (the "License"); you may not use this file except in
compliance with the License. You should have received a copy of the
Erlang Public License along with this software. If not, it can be
retrieved online at http://www.erlang.org/.
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
The Initial Developer of the Original Code is Ericsson AB.
</legalnotice>
<title>Certificate records</title>
<prepared>Ingela Anderton Andin</prepared>
<responsible></responsible>
<docno></docno>
<approved></approved>
<checked></checked>
<date>2008-02-06</date>
<rev>A</rev>
<file>cert_records.xml</file>
</header>
<p>This chapter briefly describes erlang records derived from ASN1
specifications used to handle <c> X509 certificates</c> and <c>CertificationRequest</c>.
The intent is to describe the data types and not to specify the meaning of each
component for this we refer you to <url
href="http://www.ietf.org/rfc/rfc5280.txt">RFC 5280</url> and
<url href="http://www.rsa.com/rsalabs/node.asp?id=2124">PKCS-10</url>.
</p>
<p>Use the following include directive to get access to the
records and constant macros (OIDs) described in the following sections.</p>
<code> -include_lib("public_key/include/public_key.hrl"). </code>
<p>The used ASN1 specifications are available <c>asn1</c> subdirectory
of the application <c>public_key</c>.
</p>
<section>
<title>Common Data Types</title>
<p>Common non standard erlang
data types used to described the record fields in the
below sections are defined in <seealso
marker="public_key">public key reference manual </seealso> or
follows here.</p>
<p><c>time() = uct_time() | general_time()</c></p>
<p><c>uct_time() = {utcTime, "YYMMDDHHMMSSZ"} </c></p>
<p><c>general_time() = {generalTime, "YYYYMMDDHHMMSSZ"} </c></p>
<p><c>
general_name() = {rfc822Name, string()} | {dNSName, string()}
| {x400Address, string()} | {directoryName,
{rdnSequence, [#AttributeTypeAndValue'{}]}} |
| {eidPartyName, special_string()}
| {eidPartyName, special_string(), special_string()}
| {uniformResourceIdentifier, string()} | {ipAddress, string()} |
{registeredId, oid()} | {otherName, term()}
</c></p>
<p><c>
special_string() =
{teletexString, string()} | {printableString, string()} |
{universalString, string()} | {utf8String, string()} |
{bmpString, string()}
</c></p>
<p><c>
dist_reason() = unused | keyCompromise | cACompromise |
affiliationChanged | superseded | cessationOfOperation |
certificateHold | privilegeWithdrawn |
aACompromise
</c></p>
</section>
<section>
<title> PKIX Certificates</title>
<code>
#'Certificate'{
tbsCertificate, % #'TBSCertificate'{}
signatureAlgorithm, % #'AlgorithmIdentifier'{}
signature % {0, binary()} - ASN1 compact bitstring
}.
#'TBSCertificate'{
version, % v1 | v2 | v3
serialNumber, % integer()
signature, % #'AlgorithmIdentifier'{}
issuer, % {rdnSequence, [#AttributeTypeAndValue'{}]}
validity, % #'Validity'{}
subject, % {rdnSequence, [#AttributeTypeAndValue'{}]}
subjectPublicKeyInfo, % #'SubjectPublicKeyInfo'{}
issuerUniqueID, % binary() | asn1_novalue
subjectUniqueID, % binary() | asn1_novalue
extensions % [#'Extension'{}]
}.
#'AlgorithmIdentifier'{
algorithm, % oid()
parameters % der_encoded()
}.
</code>
<code>
#'OTPCertificate'{
tbsCertificate, % #'OTPTBSCertificate'{}
signatureAlgorithm, % #'SignatureAlgorithm'
signature % {0, binary()} - ASN1 compact bitstring
}.
#'OTPTBSCertificate'{
version, % v1 | v2 | v3
serialNumber, % integer()
signature, % #'SignatureAlgorithm'
issuer, % {rdnSequence, [#AttributeTypeAndValue'{}]}
validity, % #'Validity'{}
subject, % {rdnSequence, [#AttributeTypeAndValue'{}]}
subjectPublicKeyInfo, % #'OTPSubjectPublicKeyInfo'{}
issuerUniqueID, % binary() | asn1_novalue
subjectUniqueID, % binary() | asn1_novalue
extensions % [#'Extension'{}]
}.
#'SignatureAlgorithm'{
algorithm, % id_signature_algorithm()
parameters % asn1_novalue | #'Dss-Parms'{}
}.
</code>
<p><c> id_signature_algorithm() = ?oid_name_as_erlang_atom</c> for available
oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
<table>
<row>
<cell align="left" valign="middle">OID name</cell>
</row>
<row>
<cell align="left" valign="middle">id-dsa-with-sha1</cell>
</row>
<row>
<cell align="left" valign="middle">id-dsaWithSHA1 (ISO alt oid to above)</cell>
</row>
<row>
<cell align="left" valign="middle">md2WithRSAEncryption</cell>
</row>
<row>
<cell align="left" valign="middle">md5WithRSAEncryption</cell>
</row>
<row>
<cell align="left" valign="middle">sha1WithRSAEncryption</cell>
</row>
<row>
<cell align="left" valign="middle">sha-1WithRSAEncryption (ISO alt oid to above)</cell>
</row>
<row>
<cell align="left" valign="middle">sha224WithRSAEncryption</cell>
</row>
<row>
<cell align="left" valign="middle">sha256WithRSAEncryption</cell>
</row>
<row>
<cell align="left" valign="middle">sha512WithRSAEncryption</cell>
</row>
<row>
<cell align="left" valign="middle">ecdsa-with-SHA1</cell>
</row>
<tcaption>Signature algorithm oids </tcaption>
</table>
<code>
#'AttributeTypeAndValue'{
type, % id_attributes()
value % term()
}.
</code>
<p><c>id_attributes() </c></p>
<table>
<row>
<cell align="left" valign="middle">OID name</cell>
<cell align="left" valign="middle">Value type</cell>
</row>
<row>
<cell align="left" valign="middle">id-at-name</cell>
<cell align="left" valign="middle">special_string()</cell>
</row>
<row>
<cell align="left" valign="middle">id-at-surname</cell>
<cell align="left" valign="middle">special_string()</cell>
</row>
<row>
<cell align="left" valign="middle">id-at-givenName</cell>
<cell align="left" valign="middle">special_string()</cell>
</row>
<row>
<cell align="left" valign="middle">id-at-initials </cell>
<cell align="left" valign="middle">special_string()</cell>
</row>
<row>
<cell align="left" valign="middle">id-at-generationQualifier</cell>
<cell align="left" valign="middle">special_string()</cell>
</row>
<row>
<cell align="left" valign="middle">id-at-commonName</cell>
<cell align="left" valign="middle">special_string()</cell>
</row>
<row>
<cell align="left" valign="middle">id-at-localityName</cell>
<cell align="left" valign="middle">special_string()</cell>
</row>
<row>
<cell align="left" valign="middle">id-at-stateOrProvinceName</cell>
<cell align="left" valign="middle">special_string()</cell>
</row>
<row>
<cell align="left" valign="middle">id-at-organizationName</cell>
<cell align="left" valign="middle">special_string()</cell>
</row>
<row>
<cell align="left" valign="middle">id-at-title</cell>
<cell align="left" valign="middle">special_string()</cell>
</row>
<row>
<cell align="left" valign="middle">id-at-dnQualifier</cell>
<cell align="left" valign="middle">{printableString, string()}</cell>
</row>
<row>
<cell align="left" valign="middle">id-at-countryName</cell>
<cell align="left" valign="middle">{printableString, string()}</cell>
</row>
<row>
<cell align="left" valign="middle">id-at-serialNumber</cell>
<cell align="left" valign="middle">{printableString, string()}</cell>
</row>
<row>
<cell align="left" valign="middle">id-at-pseudonym</cell>
<cell align="left" valign="middle">special_string()</cell>
</row>
<tcaption>Attribute oids </tcaption>
</table>
<code>
#'Validity'{
notBefore, % time()
notAfter % time()
}.
#'SubjectPublicKeyInfo'{
algorithm, % #AlgorithmIdentifier{}
subjectPublicKey % binary()
}.
#'SubjectPublicKeyInfoAlgorithm'{
algorithm, % id_public_key_algorithm()
parameters % public_key_params()
}.
</code>
<p><c> id_public_key_algorithm() </c></p>
<table>
<row>
<cell align="left" valign="middle">OID name</cell>
</row>
<row>
<cell align="left" valign="middle">rsaEncryption</cell>
</row>
<row>
<cell align="left" valign="middle">id-dsa</cell>
</row>
<row>
<cell align="left" valign="middle">dhpublicnumber</cell>
</row>
<row>
<cell align="left" valign="middle">id-keyExchangeAlgorithm</cell>
</row>
<row>
<cell align="left" valign="middle">id-ecPublicKey</cell>
</row>
<tcaption>Public key algorithm oids </tcaption>
</table>
<code>
#'Extension'{
extnID, % id_extensions() | oid()
critical, % boolean()
extnValue % der_encoded()
}.
</code>
<p><c>id_extensions()</c>
<seealso marker="#StdCertExt">Standard Certificate Extensions</seealso>,
<seealso marker="#PrivIntExt">Private Internet Extensions</seealso>,
<seealso marker="#CRLCertExt">CRL Extensions</seealso> and
<seealso marker="#CRLEntryExt">CRL Entry Extensions</seealso>.
</p>
</section>
<section>
<marker id="StdCertExt"></marker>
<title>Standard certificate extensions</title>
<table>
<row>
<cell align="left" valign="middle">OID name</cell>
<cell align="left" valign="middle">Value type</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-authorityKeyIdentifier</cell>
<cell align="left" valign="middle">#'AuthorityKeyIdentifier'{}</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-subjectKeyIdentifier</cell>
<cell align="left" valign="middle">oid()</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-keyUsage</cell>
<cell align="left" valign="middle"> [key_usage()]</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-privateKeyUsagePeriod</cell>
<cell align="left" valign="middle">#'PrivateKeyUsagePeriod'{}</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-certificatePolicies</cell>
<cell align="left" valign="middle">#'PolicyInformation'{}</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-policyMappings</cell>
<cell align="left" valign="middle">#'PolicyMappings_SEQOF'{}</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-subjectAltName</cell>
<cell align="left" valign="middle">general_name()</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-issuerAltName</cell>
<cell align="left" valign="middle">general_name()</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-subjectDirectoryAttributes</cell>
<cell align="left" valign="middle"> [#'Attribute'{}]</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-basicConstraints</cell>
<cell align="left" valign="middle">#'BasicConstraints'{}</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-nameConstraints</cell>
<cell align="left" valign="middle">#'NameConstraints'{}</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-policyConstraints</cell>
<cell align="left" valign="middle">#'PolicyConstraints'{}</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-extKeyUsage</cell>
<cell align="left" valign="middle">[id_key_purpose()]</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-cRLDistributionPoints</cell>
<cell align="left" valign="middle">[#'DistributionPoint'{}]</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-inhibitAnyPolicy</cell>
<cell align="left" valign="middle">integer()</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-freshestCRL</cell>
<cell align="left" valign="middle">[#'DistributionPoint'{}]</cell>
</row>
<tcaption>Standard Certificate Extensions</tcaption>
</table>
<p><c>
key_usage() = digitalSignature | nonRepudiation | keyEncipherment|
dataEncipherment | keyAgreement | keyCertSign | cRLSign | encipherOnly |
decipherOnly
</c></p>
<p><c> id_key_purpose()</c></p>
<table>
<row>
<cell align="left" valign="middle">OID name</cell>
</row>
<row>
<cell align="left" valign="middle">id-kp-serverAuth</cell>
</row>
<row>
<cell align="left" valign="middle">id-kp-clientAuth</cell>
</row>
<row>
<cell align="left" valign="middle">id-kp-codeSigning</cell>
</row>
<row>
<cell align="left" valign="middle">id-kp-emailProtection</cell>
</row>
<row>
<cell align="left" valign="middle">id-kp-timeStamping</cell>
</row>
<row>
<cell align="left" valign="middle">id-kp-OCSPSigning</cell>
</row>
<tcaption>Key purpose oids </tcaption>
</table>
<code>
#'AuthorityKeyIdentifier'{
keyIdentifier, % oid()
authorityCertIssuer, % general_name()
authorityCertSerialNumber % integer()
}.
#'PrivateKeyUsagePeriod'{
notBefore, % general_time()
notAfter % general_time()
}.
#'PolicyInformation'{
policyIdentifier, % oid()
policyQualifiers % [#PolicyQualifierInfo{}]
}.
#'PolicyQualifierInfo'{
policyQualifierId, % oid()
qualifier % string() | #'UserNotice'{}
}.
#'UserNotice'{
noticeRef, % #'NoticeReference'{}
explicitText % string()
}.
#'NoticeReference'{
organization, % string()
noticeNumbers % [integer()]
}.
#'PolicyMappings_SEQOF'{
issuerDomainPolicy, % oid()
subjectDomainPolicy % oid()
}.
#'Attribute'{
type, % oid()
values % [der_encoded()]
}).
#'BasicConstraints'{
cA, % boolean()
pathLenConstraint % integer()
}).
#'NameConstraints'{
permittedSubtrees, % [#'GeneralSubtree'{}]
excludedSubtrees % [#'GeneralSubtree'{}]
}).
#'GeneralSubtree'{
base, % general_name()
minimum, % integer()
maximum % integer()
}).
#'PolicyConstraints'{
requireExplicitPolicy, % integer()
inhibitPolicyMapping % integer()
}).
#'DistributionPoint'{
distributionPoint, % {fullName, [general_name()]} | {nameRelativeToCRLIssuer,
[#AttributeTypeAndValue{}]}
reasons, % [dist_reason()]
cRLIssuer % [general_name()]
}).
</code>
</section>
<section>
<marker id="PrivIntExt"></marker>
<title>Private Internet Extensions</title>
<table>
<row>
<cell align="left" valign="middle">OID name</cell>
<cell align="left" valign="middle">Value type</cell>
</row>
<row>
<cell align="left" valign="middle">id-pe-authorityInfoAccess</cell>
<cell align="left" valign="middle">[#'AccessDescription'{}]</cell>
</row>
<row>
<cell align="left" valign="middle">id-pe-subjectInfoAccess</cell>
<cell align="left" valign="middle">[#'AccessDescription'{}]</cell>
</row>
<tcaption>Private Internet Extensions</tcaption>
</table>
<code>
#'AccessDescription'{
accessMethod, % oid()
accessLocation % general_name()
}).
</code>
</section>
<section>
<title> CRL and CRL Extensions Profile</title>
<code>
#'CertificateList'{
tbsCertList, % #'TBSCertList{}
signatureAlgorithm, % #'AlgorithmIdentifier'{}
signature % {0, binary()} - ASN1 compact bitstring
}).
#'TBSCertList'{
version, % v2 (if defined)
signature, % #AlgorithmIdentifier{}
issuer, % {rdnSequence, [#AttributeTypeAndValue'{}]}
thisUpdate, % time()
nextUpdate, % time()
revokedCertificates, % [#'TBSCertList_revokedCertificates_SEQOF'{}]
crlExtensions % [#'Extension'{}]
}).
#'TBSCertList_revokedCertificates_SEQOF'{
userCertificate, % integer()
revocationDate, % timer()
crlEntryExtensions % [#'Extension'{}]
}).
</code>
<section>
<marker id="CRLCertExt"></marker>
<title>CRL Extensions </title>
<table>
<row>
<cell align="left" valign="middle">OID name</cell>
<cell align="left" valign="middle">Value type</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-authorityKeyIdentifier</cell>
<cell align="left" valign="middle">#'AuthorityKeyIdentifier{}</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-issuerAltName</cell>
<cell align="left" valign="middle">{rdnSequence, [#AttributeTypeAndValue'{}]}</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-cRLNumber</cell>
<cell align="left" valign="middle">integer()</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-deltaCRLIndicator</cell>
<cell align="left" valign="middle">integer()</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-issuingDistributionPoint</cell>
<cell align="left" valign="middle">#'IssuingDistributionPoint'{}</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-freshestCRL</cell>
<cell align="left" valign="middle">[#'Distributionpoint'{}]</cell>
</row>
<tcaption>CRL Extensions</tcaption>
</table>
<code>
#'IssuingDistributionPoint'{
distributionPoint, % {fullName, [general_name()]} | {nameRelativeToCRLIssuer,
[#AttributeTypeAndValue'{}]}
onlyContainsUserCerts, % boolean()
onlyContainsCACerts, % boolean()
onlySomeReasons, % [dist_reason()]
indirectCRL, % boolean()
onlyContainsAttributeCerts % boolean()
}).
</code>
</section>
<section>
<marker id="CRLEntryExt"></marker>
<title> CRL Entry Extensions </title>
<table>
<row>
<cell align="left" valign="middle">OID name</cell>
<cell align="left" valign="middle">Value type</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-cRLReason</cell>
<cell align="left" valign="middle">crl_reason()</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-holdInstructionCode</cell>
<cell align="left" valign="middle">oid()</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-invalidityDate</cell>
<cell align="left" valign="middle">general_time()</cell>
</row>
<row>
<cell align="left" valign="middle">id-ce-certificateIssuer</cell>
<cell align="left" valign="middle">general_name()</cell>
</row>
<tcaption>CRL Entry Extensions</tcaption>
</table>
<p><c>
crl_reason() = unspecified | keyCompromise | cACompromise |
affiliationChanged | superseded | cessationOfOperation |
certificateHold | removeFromCRL | privilegeWithdrawn |
aACompromise
</c></p>
</section>
<section>
<marker id="PKCS10"></marker>
<title>PKCS#10 Certification Request</title>
<code>
#'CertificationRequest'{
certificationRequestInfo #'CertificationRequestInfo'{},
signatureAlgorithm #'CertificationRequest_signatureAlgorithm'{}}.
signature {0, binary()} - ASN1 compact bitstring
}
#'CertificationRequestInfo'{
version atom(),
subject {rdnSequence, [#AttributeTypeAndValue'{}]} ,
subjectPKInfo #'CertificationRequestInfo_subjectPKInfo'{},
attributes [#'AttributePKCS-10' {}]
}
#'CertificationRequestInfo_subjectPKInfo'{
algorithm #'CertificationRequestInfo_subjectPKInfo_algorithm'{}
subjectPublicKey {0, binary()} - ASN1 compact bitstring
}
#'CertificationRequestInfo_subjectPKInfo_algorithm'{
algorithm = oid(),
parameters = der_encoded()
}
#'CertificationRequest_signatureAlgorithm'{
algorithm = oid(),
parameters = der_encoded()
}
#'AttributePKCS-10'{
type = oid(),
values = [der_encoded()]
}
</code>
</section>
</section>
</chapter>