123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254 |
- This is some preliminary documentation for OpenSSL.
- Contents:
- OpenSSL X509V3 extension configuration
- X509V3 Extension code: programmers guide
- PKCS#12 Library
- ==============================================================================
- OpenSSL X509V3 extension configuration
- ==============================================================================
- OpenSSL X509V3 extension configuration: preliminary documentation.
- INTRODUCTION.
- For OpenSSL 0.9.2 the extension code has be considerably enhanced. It is now
- possible to add and print out common X509 V3 certificate and CRL extensions.
- BEGINNERS NOTE
- For most simple applications you don't need to know too much about extensions:
- the default openssl.cnf values will usually do sensible things.
- If you want to know more you can initially quickly look through the sections
- describing how the standard OpenSSL utilities display and add extensions and
- then the list of supported extensions.
- For more technical information about the meaning of extensions see:
- http://www.imc.org/ietf-pkix/
- http://home.netscape.com/eng/security/certs.html
- PRINTING EXTENSIONS.
- Extension values are automatically printed out for supported extensions.
- openssl x509 -in cert.pem -text
- openssl crl -in crl.pem -text
- will give information in the extension printout, for example:
- X509v3 extensions:
- X509v3 Basic Constraints:
- CA:TRUE
- X509v3 Subject Key Identifier:
- 73:FE:F7:59:A7:E1:26:84:44:D6:44:36:EE:79:1A:95:7C:B1:4B:15
- X509v3 Authority Key Identifier:
- keyid:73:FE:F7:59:A7:E1:26:84:44:D6:44:36:EE:79:1A:95:7C:B1:4B:15, DirName:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/Email=email@1.address/Email=email@2.address, serial:00
- X509v3 Key Usage:
- Certificate Sign, CRL Sign
- X509v3 Subject Alternative Name:
- email:email@1.address, email:email@2.address
- CONFIGURATION FILES.
- The OpenSSL utilities 'ca' and 'req' can now have extension sections listing
- which certificate extensions to include. In each case a line:
- x509_extensions = extension_section
- indicates which section contains the extensions. In the case of 'req' the
- extension section is used when the -x509 option is present to create a
- self signed root certificate.
- The 'x509' utility also supports extensions when it signs a certificate.
- The -extfile option is used to set the configuration file containing the
- extensions. In this case a line with:
- extensions = extension_section
- in the nameless (default) section is used. If no such line is included then
- it uses the default section.
- You can also add extensions to CRLs: a line
- crl_extensions = crl_extension_section
- will include extensions when the -gencrl option is used with the 'ca' utility.
- You can add any extension to a CRL but of the supported extensions only
- issuerAltName and authorityKeyIdentifier make any real sense. Note: these are
- CRL extensions NOT CRL *entry* extensions which cannot currently be generated.
- CRL entry extensions can be displayed.
- NB. At this time Netscape Communicator rejects V2 CRLs: to get an old V1 CRL
- you should not include a crl_extensions line in the configuration file.
- As with all configuration files you can use the inbuilt environment expansion
- to allow the values to be passed in the environment. Therefore if you have
- several extension sections used for different purposes you can have a line:
- x509_extensions = $ENV::ENV_EXT
- and set the ENV_EXT environment variable before calling the relevant utility.
- EXTENSION SYNTAX.
- Extensions have the basic form:
- extension_name=[critical,] extension_options
- the use of the critical option makes the extension critical. Extreme caution
- should be made when using the critical flag. If an extension is marked
- as critical then any client that does not understand the extension should
- reject it as invalid. Some broken software will reject certificates which
- have *any* critical extensions (these violates PKIX but we have to live
- with it).
- There are three main types of extension: string extensions, multi-valued
- extensions, and raw extensions.
- String extensions simply have a string which contains either the value itself
- or how it is obtained.
- For example:
- nsComment="This is a Comment"
- Multi-valued extensions have a short form and a long form. The short form
- is a list of names and values:
- basicConstraints=critical,CA:true,pathlen:1
- The long form allows the values to be placed in a separate section:
- basicConstraints=critical,@bs_section
- [bs_section]
- CA=true
- pathlen=1
- Both forms are equivalent. However it should be noted that in some cases the
- same name can appear multiple times, for example,
- subjectAltName=email:steve@here,email:steve@there
- in this case an equivalent long form is:
- subjectAltName=@alt_section
- [alt_section]
- email.1=steve@here
- email.2=steve@there
- This is because the configuration file code cannot handle the same name
- occurring twice in the same section.
- The syntax of raw extensions is governed by the extension code: it can
- for example contain data in multiple sections. The correct syntax to
- use is defined by the extension code itself: check out the certificate
- policies extension for an example.
- There are two ways to encode arbitrary extensions.
- The first way is to use the word ASN1 followed by the extension content
- using the same syntax as ASN1_generate_nconf(). For example:
- 1.2.3.4=critical,ASN1:UTF8String:Some random data
- 1.2.3.4=ASN1:SEQUENCE:seq_sect
- [seq_sect]
- field1 = UTF8:field1
- field2 = UTF8:field2
- It is also possible to use the word DER to include arbitrary data in any
- extension.
- 1.2.3.4=critical,DER:01:02:03:04
- 1.2.3.4=DER:01020304
- The value following DER is a hex dump of the DER encoding of the extension
- Any extension can be placed in this form to override the default behaviour.
- For example:
- basicConstraints=critical,DER:00:01:02:03
- WARNING: DER should be used with caution. It is possible to create totally
- invalid extensions unless care is taken.
- CURRENTLY SUPPORTED EXTENSIONS.
- If you aren't sure about extensions then they can be largely ignored: its only
- when you want to do things like restrict certificate usage when you need to
- worry about them.
- The only extension that a beginner might want to look at is Basic Constraints.
- If in addition you want to try Netscape object signing the you should also
- look at Netscape Certificate Type.
- Literal String extensions.
- In each case the 'value' of the extension is placed directly in the
- extension. Currently supported extensions in this category are: nsBaseUrl,
- nsRevocationUrl, nsCaRevocationUrl, nsRenewalUrl, nsCaPolicyUrl,
- nsSslServerName and nsComment.
- For example:
- nsComment="This is a test comment"
- Bit Strings.
- Bit string extensions just consist of a list of supported bits, currently
- two extensions are in this category: PKIX keyUsage and the Netscape specific
- nsCertType.
- nsCertType (netscape certificate type) takes the flags: client, server, email,
- objsign, reserved, sslCA, emailCA, objCA.
- keyUsage (PKIX key usage) takes the flags: digitalSignature, nonRepudiation,
- keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign,
- encipherOnly, decipherOnly.
- For example:
- nsCertType=server
- keyUsage=digitalSignature, nonRepudiation
- Hints on Netscape Certificate Type.
- Other than Basic Constraints this is the only extension a beginner might
- want to use, if you want to try Netscape object signing, otherwise it can
- be ignored.
- If you want a certificate that can be used just for object signing then:
- nsCertType=objsign
- will do the job. If you want to use it as a normal end user and server
- certificate as well then
- nsCertType=objsign,email,server
- is more appropriate. You cannot use a self signed certificate for object
- signing (well Netscape signtool can but it cheats!) so you need to create
- a CA certificate and sign an end user certificate with it.
- Side note: If you want to conform to the Netscape specifications then you
- should really also set:
- nsCertType=objCA
- in the *CA* certificate for just an object signing CA and
- nsCertType=objCA,emailCA,sslCA
- for everything. Current Netscape software doesn't enforce this so it can
- be omitted.
- Basic Constraints.
- This is generally the only extension you need to worry about for simple
- applications. If you want your certificate to be usable as a CA certificate
- (in addition to an end user certificate) then you set this to:
- basicConstraints=CA:TRUE
- if you want to be certain the certificate cannot be used as a CA then do:
- basicConstraints=CA:FALSE
- The rest of this section describes more advanced usage.
- Basic constraints is a multi-valued extension that supports a CA and an
- optional pathlen option. The CA option takes the values true and false and
- pathlen takes an integer. Note if the CA option is false the pathlen option
- should be omitted.
- The pathlen parameter indicates the maximum number of CAs that can appear
- below this one in a chain. So if you have a CA with a pathlen of zero it can
- only be used to sign end user certificates and not further CAs. This all
- assumes that the software correctly interprets this extension of course.
- Examples:
- basicConstraints=CA:TRUE
- basicConstraints=critical,CA:TRUE, pathlen:0
- NOTE: for a CA to be considered valid it must have the CA option set to
- TRUE. An end user certificate MUST NOT have the CA value set to true.
- According to PKIX recommendations it should exclude the extension entirely,
- however some software may require CA set to FALSE for end entity certificates.
- Extended Key Usage.
- This extensions consists of a list of usages.
- These can either be object short names of the dotted numerical form of OIDs.
- While any OID can be used only certain values make sense. In particular the
- following PKIX, NS and MS values are meaningful:
- Value Meaning
- ----- -------
- serverAuth SSL/TLS Web Server Authentication.
- clientAuth SSL/TLS Web Client Authentication.
- codeSigning Code signing.
- emailProtection E-mail Protection (S/MIME).
- timeStamping Trusted Timestamping
- msCodeInd Microsoft Individual Code Signing (authenticode)
- msCodeCom Microsoft Commercial Code Signing (authenticode)
- msCTLSign Microsoft Trust List Signing
- msSGC Microsoft Server Gated Crypto
- msEFS Microsoft Encrypted File System
- nsSGC Netscape Server Gated Crypto
- For example, under IE5 a CA can be used for any purpose: by including a list
- of the above usages the CA can be restricted to only authorised uses.
- Note: software packages may place additional interpretations on certificate
- use, in particular some usages may only work for selected CAs. Don't for example
- expect just including msSGC or nsSGC will automatically mean that a certificate
- can be used for SGC ("step up" encryption) otherwise anyone could use it.
- Examples:
- extendedKeyUsage=critical,codeSigning,1.2.3.4
- extendedKeyUsage=nsSGC,msSGC
- Subject Key Identifier.
- This is really a string extension and can take two possible values. Either
- a hex string giving details of the extension value to include or the word
- 'hash' which then automatically follow PKIX guidelines in selecting and
- appropriate key identifier. The use of the hex string is strongly discouraged.
- Example: subjectKeyIdentifier=hash
- Authority Key Identifier.
- The authority key identifier extension permits two options. keyid and issuer:
- both can take the optional value "always".
- If the keyid option is present an attempt is made to copy the subject key
- identifier from the parent certificate. If the value "always" is present
- then an error is returned if the option fails.
- The issuer option copies the issuer and serial number from the issuer
- certificate. Normally this will only be done if the keyid option fails or
- is not included: the "always" flag will always include the value.
- Subject Alternative Name.
- The subject alternative name extension allows various literal values to be
- included in the configuration file. These include "email" (an email address)
- "URI" a uniform resource indicator, "DNS" (a DNS domain name), RID (a
- registered ID: OBJECT IDENTIFIER), IP (and IP address) and otherName.
- Also the email option include a special 'copy' value. This will automatically
- include and email addresses contained in the certificate subject name in
- the extension.
- otherName can include arbitrary data associated with an OID: the value
- should be the OID followed by a semicolon and the content in standard
- ASN1_generate_nconf() format.
- Examples:
- subjectAltName=email:copy,email:my@other.address,URI:http://my.url.here/
- subjectAltName=email:my@other.address,RID:1.2.3.4
- subjectAltName=otherName:1.2.3.4;UTF8:some other identifier
- Issuer Alternative Name.
- The issuer alternative name option supports all the literal options of
- subject alternative name. It does *not* support the email:copy option because
- that would not make sense. It does support an additional issuer:copy option
- that will copy all the subject alternative name values from the issuer
- certificate (if possible).
- Example:
- issuserAltName = issuer:copy
- Authority Info Access.
- The authority information access extension gives details about how to access
- certain information relating to the CA. Its syntax is accessOID;location
- where 'location' has the same syntax as subject alternative name (except
- that email:copy is not supported). accessOID can be any valid OID but only
- certain values are meaningful for example OCSP and caIssuers. OCSP gives the
- location of an OCSP responder: this is used by Netscape PSM and other software.
- Example:
- authorityInfoAccess = OCSP;URI:http://ocsp.my.host/
- authorityInfoAccess = caIssuers;URI:http://my.ca/ca.html
- CRL distribution points.
- This is a multi-valued extension that supports all the literal options of
- subject alternative name. Of the few software packages that currently interpret
- this extension most only interpret the URI option.
- Currently each option will set a new DistributionPoint with the fullName
- field set to the given value.
- Other fields like cRLissuer and reasons cannot currently be set or displayed:
- at this time no examples were available that used these fields.
- If you see this extension with <UNSUPPORTED> when you attempt to print it out
- or it doesn't appear to display correctly then let me know, including the
- certificate (mail me at steve@openssl.org) .
- Examples:
- crlDistributionPoints=URI:http://www.myhost.com/myca.crl
- crlDistributionPoints=URI:http://www.my.com/my.crl,URI:http://www.oth.com/my.crl
- Certificate Policies.
- This is a RAW extension. It attempts to display the contents of this extension:
- unfortunately this extension is often improperly encoded.
- The certificate policies extension will rarely be used in practice: few
- software packages interpret it correctly or at all. IE5 does partially
- support this extension: but it needs the 'ia5org' option because it will
- only correctly support a broken encoding. Of the options below only the
- policy OID, explicitText and CPS options are displayed with IE5.
- All the fields of this extension can be set by using the appropriate syntax.
- If you follow the PKIX recommendations of not including any qualifiers and just
- using only one OID then you just include the value of that OID. Multiple OIDs
- can be set separated by commas, for example:
- certificatePolicies= 1.2.4.5, 1.1.3.4
- If you wish to include qualifiers then the policy OID and qualifiers need to
- be specified in a separate section: this is done by using the @section syntax
- instead of a literal OID value.
- The section referred to must include the policy OID using the name
- policyIdentifier, cPSuri qualifiers can be included using the syntax:
- CPS.nnn=value
- userNotice qualifiers can be set using the syntax:
- userNotice.nnn=@notice
- The value of the userNotice qualifier is specified in the relevant section.
- This section can include explicitText, organization and noticeNumbers
- options. explicitText and organization are text strings, noticeNumbers is a
- comma separated list of numbers. The organization and noticeNumbers options
- (if included) must BOTH be present. If you use the userNotice option with IE5
- then you need the 'ia5org' option at the top level to modify the encoding:
- otherwise it will not be interpreted properly.
- Example:
- certificatePolicies=ia5org,1.2.3.4,1.5.6.7.8,@polsect
- [polsect]
- policyIdentifier = 1.3.5.8
- CPS.1="http://my.host.name/"
- CPS.2="http://my.your.name/"
- userNotice.1=@notice
- [notice]
- explicitText="Explicit Text Here"
- organization="Organisation Name"
- noticeNumbers=1,2,3,4
- TECHNICAL NOTE: the ia5org option changes the type of the 'organization' field,
- according to PKIX it should be of type DisplayText but Verisign uses an
- IA5STRING and IE5 needs this too.
- Display only extensions.
- Some extensions are only partially supported and currently are only displayed
- but cannot be set. These include private key usage period, CRL number, and
- CRL reason.
- ==============================================================================
- X509V3 Extension code: programmers guide
- ==============================================================================
- The purpose of the extension code is twofold. It allows an extension to be
- created from a string or structure describing its contents and it prints out an
- extension in a human or machine readable form.
- 1. Initialisation and cleanup.
- No special initialisation is needed before calling the extension functions.
- You used to have to call X509V3_add_standard_extensions(); but this is no longer
- required and this function no longer does anything.
- void X509V3_EXT_cleanup(void);
- This function should be called to cleanup the extension code if any custom
- extensions have been added. If no custom extensions have been added then this
- call does nothing. After this call all custom extension code is freed up but
- you can still use the standard extensions.
- 2. Printing and parsing extensions.
- The simplest way to print out extensions is via the standard X509 printing
- routines: if you use the standard X509_print() function, the supported
- extensions will be printed out automatically.
- The following functions allow finer control over extension display:
- int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, int flag, int indent);
- int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
- These two functions print out an individual extension to a BIO or FILE pointer.
- Currently the flag argument is unused and should be set to 0. The 'indent'
- argument is the number of spaces to indent each line.
- void *X509V3_EXT_d2i(X509_EXTENSION *ext);
- This function parses an extension and returns its internal structure. The
- precise structure you get back depends on the extension being parsed. If the
- extension if basicConstraints you will get back a pointer to a
- BASIC_CONSTRAINTS structure. Check out the source in crypto/x509v3 for more
- details about the structures returned. The returned structure should be freed
- after use using the relevant free function, BASIC_CONSTRAINTS_free() for
- example.
- void * X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
- void * X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
- void * X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
- void * X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx);
- These functions combine the operations of searching for extensions and
- parsing them. They search a certificate, a CRL a CRL entry or a stack
- of extensions respectively for extension whose NID is 'nid' and return
- the parsed result of NULL if an error occurred. For example:
- BASIC_CONSTRAINTS *bs;
- bs = X509_get_ext_d2i(cert, NID_basic_constraints, NULL, NULL);
- This will search for the basicConstraints extension and either return
- it value or NULL. NULL can mean either the extension was not found, it
- occurred more than once or it could not be parsed.
- If 'idx' is NULL then an extension is only parsed if it occurs precisely
- once. This is standard behaviour because extensions normally cannot occur
- more than once. If however more than one extension of the same type can
- occur it can be used to parse successive extensions for example:
- int i;
- void *ext;
- i = -1;
- for(;;) {
- ext = X509_get_ext_d2i(x, nid, crit, &idx);
- if(ext == NULL) break;
- /* Do something with ext */
- }
- If 'crit' is not NULL and the extension was found then the int it points to
- is set to 1 for critical extensions and 0 for non critical. Therefore if the
- function returns NULL but 'crit' is set to 0 or 1 then the extension was
- found but it could not be parsed.
- The int pointed to by crit will be set to -1 if the extension was not found
- and -2 if the extension occurred more than once (this will only happen if
- idx is NULL). In both cases the function will return NULL.
- 3. Generating extensions.
- An extension will typically be generated from a configuration file, or some
- other kind of configuration database.
- int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
- X509 *cert);
- int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
- X509_CRL *crl);
- These functions add all the extensions in the given section to the given
- certificate or CRL. They will normally be called just before the certificate
- or CRL is due to be signed. Both return 0 on error on non zero for success.
- In each case 'conf' is the LHASH pointer of the configuration file to use
- and 'section' is the section containing the extension details.
- See the 'context functions' section for a description of the ctx parameter.
- X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name,
- char *value);
- This function returns an extension based on a name and value pair, if the
- pair will not need to access other sections in a config file (or there is no
- config file) then the 'conf' parameter can be set to NULL.
- X509_EXTENSION *X509V3_EXT_conf_nid(char *conf, X509V3_CTX *ctx, int nid,
- char *value);
- This function creates an extension in the same way as X509V3_EXT_conf() but
- takes the NID of the extension rather than its name.
- For example to produce basicConstraints with the CA flag and a path length of
- 10:
- x = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints,"CA:TRUE,pathlen:10");
- X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
- This function sets up an extension from its internal structure. The ext_nid
- parameter is the NID of the extension and 'crit' is the critical flag.
- 4. Context functions.
- The following functions set and manipulate an extension context structure.
- The purpose of the extension context is to allow the extension code to
- access various structures relating to the "environment" of the certificate:
- for example the issuers certificate or the certificate request.
- void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
- X509_REQ *req, X509_CRL *crl, int flags);
- This function sets up an X509V3_CTX structure with details of the certificate
- environment: specifically the issuers certificate, the subject certificate,
- the certificate request and the CRL: if these are not relevant or not
- available then they can be set to NULL. The 'flags' parameter should be set
- to zero.
- X509V3_set_ctx_test(ctx)
- This macro is used to set the 'ctx' structure to a 'test' value: this is to
- allow the syntax of an extension (or configuration file) to be tested.
- X509V3_set_ctx_nodb(ctx)
- This macro is used when no configuration database is present.
- void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash);
- This function is used to set the configuration database when it is an LHASH
- structure: typically a configuration file.
- The following functions are used to access a configuration database: they
- should only be used in RAW extensions.
- char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
- This function returns the value of the parameter "name" in "section", or NULL
- if there has been an error.
- void X509V3_string_free(X509V3_CTX *ctx, char *str);
- This function frees up the string returned by the above function.
- STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section);
- This function returns a whole section as a STACK_OF(CONF_VALUE) .
- void X509V3_section_free( X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section);
- This function frees up the STACK returned by the above function.
- Note: it is possible to use the extension code with a custom configuration
- database. To do this the "db_meth" element of the X509V3_CTX structure should
- be set to an X509V3_CTX_METHOD structure. This structure contains the following
- function pointers:
- char * (*get_string)(void *db, char *section, char *value);
- STACK_OF(CONF_VALUE) * (*get_section)(void *db, char *section);
- void (*free_string)(void *db, char * string);
- void (*free_section)(void *db, STACK_OF(CONF_VALUE) *section);
- these will be called and passed the 'db' element in the X509V3_CTX structure
- to access the database. If a given function is not implemented or not required
- it can be set to NULL.
- 5. String helper functions.
- There are several "i2s" and "s2i" functions that convert structures to and
- from ASCII strings. In all the "i2s" cases the returned string should be
- freed using Free() after use. Since some of these are part of other extension
- code they may take a 'method' parameter. Unless otherwise stated it can be
- safely set to NULL.
- char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct);
- This returns a hex string from an ASN1_OCTET_STRING.
- char * i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint);
- char * i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
- These return a string decimal representations of an ASN1_INTEGER and an
- ASN1_ENUMERATED type, respectively.
- ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
- X509V3_CTX *ctx, char *str);
- This converts an ASCII hex string to an ASN1_OCTET_STRING.
- ASN1_INTEGER * s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value);
- This converts a decimal ASCII string into an ASN1_INTEGER.
- 6. Multi valued extension helper functions.
- The following functions can be used to manipulate STACKs of CONF_VALUE
- structures, as used by multi valued extensions.
- int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
- This function expects a boolean value in 'value' and sets 'asn1_bool' to
- it. That is it sets it to 0 for FALSE or 0xff for TRUE. The following
- strings are acceptable: "TRUE", "true", "Y", "y", "YES", "yes", "FALSE"
- "false", "N", "n", "NO" or "no".
- int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
- This accepts a decimal integer of arbitrary length and sets an ASN1_INTEGER.
- int X509V3_add_value(const char *name, const char *value,
- STACK_OF(CONF_VALUE) **extlist);
- This simply adds a string name and value pair.
- int X509V3_add_value_uchar(const char *name, const unsigned char *value,
- STACK_OF(CONF_VALUE) **extlist);
- The same as above but for an unsigned character value.
- int X509V3_add_value_bool(const char *name, int asn1_bool,
- STACK_OF(CONF_VALUE) **extlist);
- This adds either "TRUE" or "FALSE" depending on the value of 'asn1_bool'
- int X509V3_add_value_bool_nf(char *name, int asn1_bool,
- STACK_OF(CONF_VALUE) **extlist);
- This is the same as above except it adds nothing if asn1_bool is FALSE.
- int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
- STACK_OF(CONF_VALUE) **extlist);
- This function adds the value of the ASN1_INTEGER in decimal form.
- 7. Other helper functions.
- <to be added>
- ADDING CUSTOM EXTENSIONS.
- Currently there are three types of supported extensions.
- String extensions are simple strings where the value is placed directly in the
- extensions, and the string returned is printed out.
- Multi value extensions are passed a STACK_OF(CONF_VALUE) name and value pairs
- or return a STACK_OF(CONF_VALUE).
- Raw extensions are just passed a BIO or a value and it is the extensions
- responsibility to handle all the necessary printing.
- There are two ways to add an extension. One is simply as an alias to an already
- existing extension. An alias is an extension that is identical in ASN1 structure
- to an existing extension but has a different OBJECT IDENTIFIER. This can be
- done by calling:
- int X509V3_EXT_add_alias(int nid_to, int nid_from);
- 'nid_to' is the new extension NID and 'nid_from' is the already existing
- extension NID.
- Alternatively an extension can be written from scratch. This involves writing
- the ASN1 code to encode and decode the extension and functions to print out and
- generate the extension from strings. The relevant functions are then placed in
- a X509V3_EXT_METHOD structure and int X509V3_EXT_add(X509V3_EXT_METHOD *ext);
- called.
- The X509V3_EXT_METHOD structure is described below.
- strut {
- int ext_nid;
- int ext_flags;
- X509V3_EXT_NEW ext_new;
- X509V3_EXT_FREE ext_free;
- X509V3_EXT_D2I d2i;
- X509V3_EXT_I2D i2d;
- X509V3_EXT_I2S i2s;
- X509V3_EXT_S2I s2i;
- X509V3_EXT_I2V i2v;
- X509V3_EXT_V2I v2i;
- X509V3_EXT_R2I r2i;
- X509V3_EXT_I2R i2r;
- void *usr_data;
- };
- The elements have the following meanings.
- ext_nid is the NID of the object identifier of the extension.
- ext_flags is set of flags. Currently the only external flag is
- X509V3_EXT_MULTILINE which means a multi valued extensions
- should be printed on separate lines.
- usr_data is an extension specific pointer to any relevant data. This
- allows extensions to share identical code but have different
- uses. An example of this is the bit string extension which uses
- usr_data to contain a list of the bit names.
- All the remaining elements are function pointers.
- ext_new is a pointer to a function that allocates memory for the
- extension ASN1 structure: for example ASN1_OBJECT_new().
- ext_free is a pointer to a function that free up memory of the extension
- ASN1 structure: for example ASN1_OBJECT_free().
- d2i is the standard ASN1 function that converts a DER buffer into
- the internal ASN1 structure: for example d2i_ASN1_IA5STRING().
- i2d is the standard ASN1 function that converts the internal
- structure into the DER representation: for example
- i2d_ASN1_IA5STRING().
- The remaining functions are depend on the type of extension. One i2X and
- one X2i should be set and the rest set to NULL. The types set do not need
- to match up, for example the extension could be set using the multi valued
- v2i function and printed out using the raw i2r.
- All functions have the X509V3_EXT_METHOD passed to them in the 'method'
- parameter and an X509V3_CTX structure. Extension code can then access the
- parent structure via the 'method' parameter to for example make use of the value
- of usr_data. If the code needs to use detail relating to the request it can
- use the 'ctx' parameter.
- A note should be given here about the 'flags' member of the 'ctx' parameter.
- If it has the value CTX_TEST then the configuration syntax is being checked
- and no actual certificate or CRL exists. Therefore any attempt in the config
- file to access such information should silently succeed. If the syntax is OK
- then it should simply return a (possibly bogus) extension, otherwise it
- should return NULL.
- char *i2s(struct v3_ext_method *method, void *ext);
- This function takes the internal structure in the ext parameter and returns
- a Malloc'ed string representing its value.
- void * s2i(struct v3_ext_method *method, struct v3_ext_ctx *ctx, char *str);
- This function takes the string representation in the ext parameter and returns
- an allocated internal structure: ext_free() will be used on this internal
- structure after use.
- i2v and v2i handle a STACK_OF(CONF_VALUE):
- typedef struct
- {
- char *section;
- char *name;
- char *value;
- } CONF_VALUE;
- Only the name and value members are currently used.
- STACK_OF(CONF_VALUE) * i2v(struct v3_ext_method *method, void *ext);
- This function is passed the internal structure in the ext parameter and
- returns a STACK of CONF_VALUE structures. The values of name, value,
- section and the structure itself will be freed up with Free after use.
- Several helper functions are available to add values to this STACK.
- void * v2i(struct v3_ext_method *method, struct v3_ext_ctx *ctx,
- STACK_OF(CONF_VALUE) *values);
- This function takes a STACK_OF(CONF_VALUE) structures and should set the
- values of the external structure. This typically uses the name element to
- determine which structure element to set and the value element to determine
- what to set it to. Several helper functions are available for this
- purpose (see above).
- int i2r(struct v3_ext_method *method, void *ext, BIO *out, int indent);
- This function is passed the internal extension structure in the ext parameter
- and sends out a human readable version of the extension to out. The 'indent'
- parameter should be noted to determine the necessary amount of indentation
- needed on the output.
- void * r2i(struct v3_ext_method *method, struct v3_ext_ctx *ctx, char *str);
- This is just passed the string representation of the extension. It is intended
- to be used for more elaborate extensions where the standard single and multi
- valued options are insufficient. They can use the 'ctx' parameter to parse the
- configuration database themselves. See the context functions section for details
- of how to do this.
- Note: although this type takes the same parameters as the "r2s" function there
- is a subtle difference. Whereas an "r2i" function can access a configuration
- database an "s2i" function MUST NOT. This is so the internal code can safely
- assume that an "s2i" function will work without a configuration database.
- ==============================================================================
- PKCS#12 Library
- ==============================================================================
- This section describes the internal PKCS#12 support. There are very few
- differences between the old external library and the new internal code at
- present. This may well change because the external library will not be updated
- much in future.
- This version now includes a couple of high level PKCS#12 functions which
- generally "do the right thing" and should make it much easier to handle PKCS#12
- structures.
- HIGH LEVEL FUNCTIONS.
- For most applications you only need concern yourself with the high level
- functions. They can parse and generate simple PKCS#12 files as produced by
- Netscape and MSIE or indeed any compliant PKCS#12 file containing a single
- private key and certificate pair.
- 1. Initialisation and cleanup.
- No special initialisation is needed for the internal PKCS#12 library: the
- standard SSLeay_add_all_algorithms() is sufficient. If you do not wish to
- add all algorithms (you should at least add SHA1 though) then you can manually
- initialise the PKCS#12 library with:
- PKCS12_PBE_add();
- The memory allocated by the PKCS#12 library is freed up when EVP_cleanup() is
- called or it can be directly freed with:
- EVP_PBE_cleanup();
- after this call (or EVP_cleanup() ) no more PKCS#12 library functions should
- be called.
- 2. I/O functions.
- i2d_PKCS12_bio(bp, p12)
- This writes out a PKCS12 structure to a BIO.
- i2d_PKCS12_fp(fp, p12)
- This is the same but for a FILE pointer.
- d2i_PKCS12_bio(bp, p12)
- This reads in a PKCS12 structure from a BIO.
- d2i_PKCS12_fp(fp, p12)
- This is the same but for a FILE pointer.
- 3. High level functions.
- 3.1 Parsing with PKCS12_parse().
- int PKCS12_parse(PKCS12 *p12, char *pass, EVP_PKEY **pkey, X509 **cert,
- STACK **ca);
- This function takes a PKCS12 structure and a password (ASCII, null terminated)
- and returns the private key, the corresponding certificate and any CA
- certificates. If any of these is not required it can be passed as a NULL.
- The 'ca' parameter should be either NULL, a pointer to NULL or a valid STACK
- structure. Typically to read in a PKCS#12 file you might do:
- p12 = d2i_PKCS12_fp(fp, NULL);
- PKCS12_parse(p12, password, &pkey, &cert, NULL); /* CAs not wanted */
- PKCS12_free(p12);
- 3.2 PKCS#12 creation with PKCS12_create().
- PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
- STACK *ca, int nid_key, int nid_cert, int iter,
- int mac_iter, int keytype);
- This function will create a PKCS12 structure from a given password, name,
- private key, certificate and optional STACK of CA certificates. The remaining
- 5 parameters can be set to 0 and sensible defaults will be used.
- The parameters nid_key and nid_cert are the key and certificate encryption
- algorithms, iter is the encryption iteration count, mac_iter is the MAC
- iteration count and keytype is the type of private key. If you really want
- to know what these last 5 parameters do then read the low level section.
- Typically to create a PKCS#12 file the following could be used:
- p12 = PKCS12_create(pass, "My Certificate", pkey, cert, NULL, 0,0,0,0,0);
- i2d_PKCS12_fp(fp, p12);
- PKCS12_free(p12);
- 3.3 Changing a PKCS#12 structure password.
- int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass);
- This changes the password of an already existing PKCS#12 structure. oldpass
- is the old password and newpass is the new one. An error occurs if the old
- password is incorrect.
- LOW LEVEL FUNCTIONS.
- In some cases the high level functions do not provide the necessary
- functionality. For example if you want to generate or parse more complex
- PKCS#12 files. The sample pkcs12 application uses the low level functions
- to display details about the internal structure of a PKCS#12 file.
- Introduction.
- This is a brief description of how a PKCS#12 file is represented internally:
- some knowledge of PKCS#12 is assumed.
- A PKCS#12 object contains several levels.
- At the lowest level is a PKCS12_SAFEBAG. This can contain a certificate, a
- CRL, a private key, encrypted or unencrypted, a set of safebags (so the
- structure can be nested) or other secrets (not documented at present).
- A safebag can optionally have attributes, currently these are: a unicode
- friendlyName (a Unicode string) or a localKeyID (a string of bytes).
- At the next level is an authSafe which is a set of safebags collected into
- a PKCS#7 ContentInfo. This can be just plain data, or encrypted itself.
- At the top level is the PKCS12 structure itself which contains a set of
- authSafes in an embedded PKCS#7 Contentinfo of type data. In addition it
- contains a MAC which is a kind of password protected digest to preserve
- integrity (so any unencrypted stuff below can't be tampered with).
- The reason for these levels is so various objects can be encrypted in various
- ways. For example you might want to encrypt a set of private keys with
- triple-DES and then include the related certificates either unencrypted or
- with lower encryption. Yes it's the dreaded crypto laws at work again which
- allow strong encryption on private keys and only weak encryption on other
- stuff.
- To build one of these things you turn all certificates and keys into safebags
- (with optional attributes). You collect the safebags into (one or more) STACKS
- and convert these into authsafes (encrypted or unencrypted). The authsafes
- are collected into a STACK and added to a PKCS12 structure. Finally a MAC
- inserted.
- Pulling one apart is basically the reverse process. The MAC is verified against
- the given password. The authsafes are extracted and each authsafe split into
- a set of safebags (possibly involving decryption). Finally the safebags are
- decomposed into the original keys and certificates and the attributes used to
- match up private key and certificate pairs.
- Anyway here are the functions that do the dirty work.
- 1. Construction functions.
- 1.1 Safebag functions.
- M_PKCS12_x5092certbag(x509)
- This macro takes an X509 structure and returns a certificate bag. The
- X509 structure can be freed up after calling this function.
- M_PKCS12_x509crl2certbag(crl)
- As above but for a CRL.
- PKCS8_PRIV_KEY_INFO *PKEY2PKCS8(EVP_PKEY *pkey)
- Take a private key and convert it into a PKCS#8 PrivateKeyInfo structure.
- Works for both RSA and DSA private keys. NB since the PKCS#8 PrivateKeyInfo
- structure contains a private key data in plain text form it should be free'd
- up as soon as it has been encrypted for security reasons (freeing up the
- structure zeros out the sensitive data). This can be done with
- PKCS8_PRIV_KEY_INFO_free().
- PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage)
- This sets the key type when a key is imported into MSIE or Outlook 98. Two
- values are currently supported: KEY_EX and KEY_SIG. KEY_EX is an exchange type
- key that can also be used for signing but its size is limited in the export
- versions of MS software to 512 bits, it is also the default. KEY_SIG is a
- signing only key but the keysize is unlimited (well 16K is supposed to work).
- If you are using the domestic version of MSIE then you can ignore this because
- KEY_EX is not limited and can be used for both.
- PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8)
- Convert a PKCS8 private key structure into a keybag. This routine embeds the
- p8 structure in the keybag so p8 should not be freed up or used after it is
- called. The p8 structure will be freed up when the safebag is freed.
- PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8)
- Convert a PKCS#8 structure into a shrouded key bag (encrypted). p8 is not
- embedded and can be freed up after use.
- int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen)
- int PKCS12_add_friendlyname(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen)
- Add a local key id or a friendlyname to a safebag.
- 1.2 Authsafe functions.
- PKCS7 *PKCS12_pack_p7data(STACK *sk)
- Take a stack of safebags and convert them into an unencrypted authsafe. The
- stack of safebags can be freed up after calling this function.
- PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, STACK *bags);
- As above but encrypted.
- 1.3 PKCS12 functions.
- PKCS12 *PKCS12_init(int mode)
- Initialise a PKCS12 structure (currently mode should be NID_pkcs7_data).
- M_PKCS12_pack_authsafes(p12, safes)
- This macro takes a STACK of authsafes and adds them to a PKCS#12 structure.
- int PKCS12_set_mac(PKCS12 *p12, unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int iter, EVP_MD *md_type);
- Add a MAC to a PKCS12 structure. If EVP_MD is NULL use SHA-1, the spec suggests
- that SHA-1 should be used.
- 2. Extraction Functions.
- 2.1 Safebags.
- M_PKCS12_bag_type(bag)
- Return the type of "bag". Returns one of the following
- NID_keyBag
- NID_pkcs8ShroudedKeyBag 7
- NID_certBag 8
- NID_crlBag 9
- NID_secretBag 10
- NID_safeContentsBag 11
- M_PKCS12_cert_bag_type(bag)
- Returns type of certificate bag, following are understood.
- NID_x509Certificate 14
- NID_sdsiCertificate 15
- M_PKCS12_crl_bag_type(bag)
- Returns crl bag type, currently only NID_crlBag is recognised.
- M_PKCS12_certbag2x509(bag)
- This macro extracts an X509 certificate from a certificate bag.
- M_PKCS12_certbag2x509crl(bag)
- As above but for a CRL.
- EVP_PKEY * PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
- Extract a private key from a PKCS8 private key info structure.
- M_PKCS12_decrypt_skey(bag, pass, passlen)
- Decrypt a shrouded key bag and return a PKCS8 private key info structure.
- Works with both RSA and DSA keys
- char *PKCS12_get_friendlyname(bag)
- Returns the friendlyName of a bag if present or NULL if none. The returned
- string is a null terminated ASCII string allocated with Malloc(). It should
- thus be freed up with Free() after use.
- 2.2 AuthSafe functions.
- M_PKCS12_unpack_p7data(p7)
- Extract a STACK of safe bags from a PKCS#7 data ContentInfo.
- #define M_PKCS12_unpack_p7encdata(p7, pass, passlen)
- As above but for an encrypted content info.
- 2.3 PKCS12 functions.
- M_PKCS12_unpack_authsafes(p12)
- Extract a STACK of authsafes from a PKCS12 structure.
- M_PKCS12_mac_present(p12)
- Check to see if a MAC is present.
- int PKCS12_verify_mac(PKCS12 *p12, unsigned char *pass, int passlen)
- Verify a MAC on a PKCS12 structure. Returns an error if MAC not present.
- Notes.
- 1. All the function return 0 or NULL on error.
- 2. Encryption based functions take a common set of parameters. These are
- described below.
- pass, passlen
- ASCII password and length. The password on the MAC is called the "integrity
- password" the encryption password is called the "privacy password" in the
- PKCS#12 documentation. The passwords do not have to be the same. If -1 is
- passed for the length it is worked out by the function itself (currently
- this is sometimes done whatever is passed as the length but that may change).
- salt, saltlen
- A 'salt' if salt is NULL a random salt is used. If saltlen is also zero a
- default length is used.
- iter
- Iteration count. This is a measure of how many times an internal function is
- called to encrypt the data. The larger this value is the longer it takes, it
- makes dictionary attacks on passwords harder. NOTE: Some implementations do
- not support an iteration count on the MAC. If the password for the MAC and
- encryption is the same then there is no point in having a high iteration
- count for encryption if the MAC has no count. The MAC could be attacked
- and the password used for the main decryption.
- pbe_nid
- This is the NID of the password based encryption method used. The following are
- supported.
- NID_pbe_WithSHA1And128BitRC4
- NID_pbe_WithSHA1And40BitRC4
- NID_pbe_WithSHA1And3_Key_TripleDES_CBC
- NID_pbe_WithSHA1And2_Key_TripleDES_CBC
- NID_pbe_WithSHA1And128BitRC2_CBC
- NID_pbe_WithSHA1And40BitRC2_CBC
- Which you use depends on the implementation you are exporting to. "Export
- grade" (i.e. cryptographically challenged) products cannot support all
- algorithms. Typically you may be able to use any encryption on shrouded key
- bags but they must then be placed in an unencrypted authsafe. Other authsafes
- may only support 40bit encryption. Of course if you are using SSLeay
- throughout you can strongly encrypt everything and have high iteration counts
- on everything.
- 3. For decryption routines only the password and length are needed.
- 4. Unlike the external version the nid's of objects are the values of the
- constants: that is NID_certBag is the real nid, therefore there is no
- PKCS12_obj_offset() function. Note the object constants are not the same as
- those of the external version. If you use these constants then you will need
- to recompile your code.
- 5. With the exception of PKCS12_MAKE_KEYBAG(), after calling any function or
- macro of the form PKCS12_MAKE_SOMETHING(other) the "other" structure can be
- reused or freed up safely.
|