diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /security/nss/doc/rst/legacy/nss_tech_notes | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'security/nss/doc/rst/legacy/nss_tech_notes')
9 files changed, 1923 insertions, 0 deletions
diff --git a/security/nss/doc/rst/legacy/nss_tech_notes/index.rst b/security/nss/doc/rst/legacy/nss_tech_notes/index.rst new file mode 100644 index 0000000000..ddd92f87cd --- /dev/null +++ b/security/nss/doc/rst/legacy/nss_tech_notes/index.rst @@ -0,0 +1,23 @@ +.. _mozilla_projects_nss_nss_tech_notes: + +NSS Tech Notes +============== + +.. container:: + + Newsgroup: `mozilla.dev.tech.crypto <news://news.mozilla.org/mozilla.dev.tech.crypto>`__ + + NSS technical notes provide latest information about new NSS features and supplementary + documentation for advanced topics in programming with NSS. + + #. TN1: `How to use the NSS ASN.1 and QuickDER decoders <nss_tech_notes/nss_tech_note1>`__. + #. TN2: `Using the PKCS #11 Module Logger <nss_tech_notes/nss_tech_note2>`__. + #. TN3: `All About Certificate Extensions <nss_tech_notes/nss_tech_note3>`__. + #. TN4: `Pulling certificate extension information out of SSL + certificates <nss_tech_notes/nss_tech_note4>`__. + #. TN5: `Using NSS to perform miscellaneous cryptographic + operations <nss_tech_notes/nss_tech_note5>`__. + #. TN6: `NSS .chk Files for the FIPS Mode <nss_tech_notes/nss_tech_note6>`__. + #. TN7: `RSA Signing and Encryption with NSS <nss_tech_notes/nss_tech_note7>`__. + #. TN8: `Background Information on libSSL's Cache Functions and + SIDs <nss_tech_notes/nss_tech_note8>`__.
\ No newline at end of file diff --git a/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note1/index.rst b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note1/index.rst new file mode 100644 index 0000000000..3b8313fd3a --- /dev/null +++ b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note1/index.rst @@ -0,0 +1,196 @@ +.. _mozilla_projects_nss_nss_tech_notes_nss_tech_note1: + +nss tech note1 +============== + +.. _how_to_use_the_nss_asn.1_and_quickder_decoders: + +`How to use the NSS ASN.1 and QuickDER decoders <#how_to_use_the_nss_asn.1_and_quickder_decoders>`__ +---------------------------------------------------------------------------------------------------- + +.. container:: + +.. _nss_technical_note_1: + +`NSS Technical Note: 1 <#nss_technical_note_1>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: + + NSS 3.6 contains several decoders for ASN.1 and DER.Two of them are extensively used and are part + of the public NSS API : + + #. The "classic" ASN.1 decoder, written by Lisa Repka . This was written to be a generic decoder, + that includes both DER (Distinguished Encoding Rules) and BER (Basic Encoding Rules).† It + handles both streaming and non-streaming input. + #. The "QuickDER" decoder, written by Julien Pierre for NSS 3.6 . This decoder was written when + performance issues were discovered with the classic decoder. It can only decode DER .† It does + not handle streaming input, and requires that all input be present before beginning to decode. + + Despite their differences, the two decoders have a lot in common. QuickDER was written to be as + compatible as possible with the classic decoder, in order to ease migration to it in areas of + critical performance bottlenecks. For this reason, I will first describe all the common + functionality of the two decoders, before outlining their differences. + The main non-streaming APIs for these two decoders have an identical prototype : + + - SECStatus SEC_ASN1DecodeItem(PRArenaPool \*pool, void \*dest, const SEC_ASN1Template \*t, + SECItem \*item); + - SECStatus SEC_QuickDERDecodeItem(PRArenaPool\* arena, void\* dest, const SEC_ASN1Template\* + templateEntry, SECItem\* src); + + Here is a description of the arguments : + + - *SECItem\* src*\ † is a structure containing a pointer to the binary data to be decoded, as + well as its size. + - *const SEC_ASN1Template\* templateEntry* is a pointer to one or more `decoder + templates <#templates>`__. The number of required templates is determined by the type of the + first template.When multiple templates are required, the pointer must point to a + NULL-terminated array of templates. The syntax of these templates is identical for both + decoders, except where noted. A "NULL Template" is a template that is all zeros, having a zero + kind.† The term "NULL-terminated array", as used throughout this document, means an array of + templates, the last of which is a NULL template. + - *void\* dest* is a pointer to the target area. This is where the decoder stores its output. + The type is undefined as it is completely dependent on the content of the decoder templates.† + This typically points to a struct that is described (or partially described) by the templates. + - *PRArenaPool\* arena* is a pointer to an NSPR arena pool. This is the arena pool from which + the decoder will allocate memory as needed. + + Decoder templates : + The SEC_ASN1Template structure tells the decoder what to do with the input data. This structure + contains four fields : + + - *kind* . This 32-bit field tells the decoder what to do with a particular component within the + input data. It is made of two parts : the lower byte, which can contain `ASN.1 + tags <#asn.1_tags>`__, and the upper 3 bytes, which can contain `decoder + modifiers <#decoder_modifiers>`__. If only an ASN.1 tag is specified without a modifier, then + the decoder will enforce the presence of a component of that type, and fail if it does not + match. If kind is an ASN.1 SEQUENCE tag (SEC_ASN1_SEQUENCE), then you must specify additional + templates in a NULL-terminated array to define the content of the of the ASN.1 SEQUENCE. If + kind is the SEC_ASN1_CHOICE modifier, you must also specify additional templates in a NULL + terminated array to list the various possible types that this component can have. In all other + cases, only the first template structure passed to the decoder will be considered, even if + additonal templates are passed in an array. When only one template is needed, you do not need + a NULL template to terminate the array. + - *offset*\ † . This field does not apply to all template types. It is only needed if the + template instructs the decoder to save some data, such as for primitive component types, or + for some modifiers where noted.When needed, it tells the decoder where in the target data to + save the current component. It is normally relative to the dest argument passed to the + decoder. If templates are nested, the offset applies to the location of the current component + within the target component, typically the decoded SEQUENCE. + - *sub*\ † . This field does not apply to all template types. If kind contains the + SEC_ASN1_INLINE or SEC_ASN1_POINTER modifiers, then it must point to the required subtemplate. + If kind contains the SEC_ASN1_XTRN or SEC_ASN1_DYNAMIC modifiers, this is a pointer to a + callback function that will dynamically return the required subtemplate. + - *size*\ † . This field does not apply to all template types. It is only required for + dynamically allocating memory for the structure if the template is being included from an + ASN.1 SEQUENCE or SEQUENCE OF, or if dynamic allocation was requested from the parent template + using the SEC_ASN1_POINTER modifier + + Here is a description of the various tags and modifiers that apply to the kind field. + *ASN.1 tags* + + | ASN.1 tags are specified in the lower byte of the kind field of the template, as noted above. + | The following is not an attempt to explain ASN.1 tags or their purposes. Rather, the goal here + is to explain what type of tags the decoder supports and which macros should be used when + defining tags in decoder templates. It should be noted that we only support an older + specification of ASN.1; multibyte tags are not currently supported. + + The 8-bit ASN.1 tags that we support are made of three parts : + + #. The ASN.1 component class type. It is specified in the upper 2 tag bits (number 6 and 7). + There are four classes of ASN.1 tags : universal, application-specific, context-specific, and + private. You can specify the class of the tag using the macros SEC_ASN1_UNIVERSAL, + SEC_ASN1_APPLICATION, SEC_ASN1_CONTEXT_SPECIFIC and SEC_ASN1_PRIVATE. Universal is the default + tag class and does not have to be specified, as the value of the class type is zero. + + #. The method type : whether the component type is constructed or primitive. This information is + stored in the next lowest tag bit (number 5). You can use the macro SEC_ASN1_CONSTRUCTED for a + constructed component type. A SEC_ASN1_PRIMITIVE macro is also provided, but does not need to + be included as it is zero. + + #. | The tag number. It is stored in the lower 5 tag bits (number 0 through 4). The ASN.1 + standard only defines tag numbers in the universal class. If you are using a tag of a + different classes, you can define your own tag number macros or specify the tag value within + the template definition. The following macros are provided for tag numbers within the + universal class : + | SEC_ASN1_BOOLEAN, SEC_ASN1_INTEGER, SEC_ASN1_BIT_STRING, SEC_ASN1_OCTET_STRING, + SEC_ASN1_NULL, SEC_ASN1_OBJECT_ID, SEC_ASN1_OBJECT_DESCRIPTOR,† SEC_ASN1_REAL, + SEC_ASN1_ENUMERATED, SEC_ASN1_EMBEDDED_PDV, SEC_ASN1_UTF8_STRING, SEC_ASN1_SEQUENCE, + SEC_ASN1_SET, SEC_ASN1_NUMERIC_STRING, SEC_ASN1_PRINTABLE_STRING, SEC_ASN1_T61_STRING, + SEC_ASN1_TELETEX_STRING, SEC_ASN1_T61_STRING, SEC_ASN1_VIDEOTEX_STRING, SEC_ASN1_IA5_STRING, + SEC_ASN1_UTC_TIME, SEC_ASN1_GENERALIZED_TIME, SEC_ASN1_GRAPHIC_STRING, + SEC_ASN1_VISIBLE_STRING, SEC_ASN1_GENERAL_STRING, SEC_ASN1_UNIVERSAL_STRING, + SEC_ASN1_BMP_STRING + + Note that for SEC_ASN1_SET and SEC_ASN1_SEQUENCE types, you must also include the method type + macro SEC_ASN1_CONSTRUCTED to construct a fully valid tag, as defined by the ASN.1 standard . + + *Decoder modifiers :* + These modifiers are also specified in the kind field of the template structure. All the values + are in the 9 - 31 bit range. + + - *SEC_ASN1_OPTIONAL*: tells the decoder that this component is optional. If the component in + the input data does not match this template, the decoder will continue processing the input + data using the next available template. + - *SEC_ASN1_EXPLICIT*: tells the decoder that explicit tagging is being used. This is always a + constructed type. It requires a subtemplate defining the types of the data within. + - *SEC_ASN1_ANY*: allows the decoder to match this template with any component type, regardless + of the tag in the input data. If used in conjunction with SEC_ASN1_OPTIONAL as part of a + sequence, this must be the last template in the template array. + - *SEC_ASN1_INLINE*: recurse into the specified subtemplate to continue processing. This is + typically used for SEC_ASN1_SEQUENCE or SEC_ASN1_CHOICE definitions, which always need to be + the first template in a template array of their own. + - *SEC_ASN1_POINTER*: similar to SEC_ASN1_INLINE, except that the memory in the target will be + allocated dynamically and a pointer to the dynamically allocated memory will be stored in the + *dest* struct at the *offset*. This requires that the subtemplate contains a non-zero size + field. + - *SEC_ASN1_GROUP*: can only be used in conjunction with a SEC_ASN1_SET or SEC_ASN1_SEQUENCE. It + tells the decoder that the component is an ASN.1 SET OF or SEQUENCE OF respectively. You can + also use the macros SEC_ASN1_SET_OF and SEC_ASN1_SEQUENCE_OF which define both the tag number + and this modifier (but still need the method type, this may be a bug). + - *SEC_ASN1_DYNAMIC* or *SEC_ASN1_XTRN* : specifies that the component format is defined in a + dynamic subtemplate. There is no difference between the two macros. The sub field of the + template points to a callback function of type SEC_ASN1TemplateChooser that returns the + subtemplate depending on the component data. + - *SEC_ASN1_SKIP*: specifies that the decoder should skip decoding of the component. + SEC_ASN1DecodeItem can only skip required components and will assert if you try to skip an + OPTIONAL component. SEC_QuickDERDecodeItem supports skipping the decoding of OPTIONAL + components if you define the tag of the component in the template + - *SEC_ASN1_INNER*: recurse into the component and saves its content, without the surrounding + ASN.1 tag and length + - *SEC_ASN1_SAVE*: saves the component data, but does not proceed to the next component if + within a SEQUENCE template array. This means the next template will reprocess the same + component. + - *SEC_ASN1_SKIP_REST*: abort the decoding. This is used in a template array within a SEQUENCE, + if you don't care about the fields at the end of it. SEC_ASN1DecodeItem only supports this + modifier in the top-level template. SEC_QuickDERDecodeItem allows it at any nested sublevel. + - *SEC_ASN1_CHOICE*: allows decoding of components that are of variable type. This must be the + first template in a NULL-terminated array. The offset parameter specifies where to store the + type identifier in the target data . Subsequent templates specify a custom identifier for each + possible component type in the size parameter . + - *SEC_ASN1_DEBUG_BREAK*: makes the decoder assert when processing the template. This option is + only supported with SEC_QuickDERDecodeItem . It is useful to debug your templates or when + writing new templates if they don't work. + + | + | *Differences between SEC_ASN1DecodeItem and SEC_QuickDERDecodeItem* + + #. The arena argument is required to be non-NULL for SEC_QuickDERDecodeItem . With + SEC_ASN1DecodeItem, it can be NULL, and if so, the decoder will allocate from the heap using + PR_Malloc . However, this usage is strongly discouraged and we recommend that you always use + an arena pool even with SEC_ASN1DecodeItem. See `bug + 175163 <http://bugzilla.mozilla.org/show_bug.cgi?id=175163>`__ for more information about the + reason for this recommendation. + #. SEC_ASN1DecodeItem will make a copy of the input data into the decoded target as needed, while + SEC_QuickDERDecodeItem will generate output with pointers into the input. This means that if + you use SEC_QuickDERDecodeItem, you must always be careful not to free the input as long as + you intend to use the decoded structure. Ideally, you should allocate the input data out of + the same arena that you are passing to the decoder. This will allow you to free both the input + data and the decoded data at once when freeing the arena. + #. SEC_ASN1DecodeItem can decode both BER and DER data, while SEC_QuickDERDecodeItem can only + decode DER data. + #. SEC_QuickDERDecodeItem does not support streaming data. This feature will most likely never be + added, as this decoder gets most of its extra speed from not making a copy of the input data, + which would be required when streaming. + #. SEC_QuickDERDecodeItem supports SEC_ASN1_OPTIONAL together with SEC_ASN1_SKIP + #. SEC_ASN1_DEBUG_BREAK is not supported by SEC_ASN1DecodeItem
\ No newline at end of file diff --git a/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note2/index.rst b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note2/index.rst new file mode 100644 index 0000000000..efc80ff3a4 --- /dev/null +++ b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note2/index.rst @@ -0,0 +1,167 @@ +.. _mozilla_projects_nss_nss_tech_notes_nss_tech_note2: + +nss tech note2 +============== + +.. container:: + + .. rubric:: Using the PKCS #11 Module Logger + :name: Using_the_PKCS_11_Module_Logger + +.. _nss_technical_note_2: + +`NSS Technical Note: 2 <#nss_technical_note_2>`__ +------------------------------------------------- + +.. container:: + + - `Modes of Operation <#modes>`__ + - `Extracting Output from Log files <#extracting>`__ + + The logger displays all activity between NSS and a specified PKCS #11 module. It works by + inserting a special set of entry points between NSS and the module. + + To enable the module logger, you must set the environment variable NSS_DEBUG_PKCS11_MODULE to the + name of the target module. For example, to log the softoken, use: + + .. code:: + + NSS_DEBUG_PKCS11_MODULE="NSS Internal PKCS #11 Module" + + Note: In the Command Prompt on Windows, do not quote the name of the target module, otherwise the + quotes are considered part of the name. For example, to log the softoken on Windows, use: + + .. code:: + + set NSS_DEBUG_PKCS11_MODULE=NSS Internal PKCS #11 Module + + The logger is available by default in debug builds. For optimized builds, NSS must be built with + the variable DEBUG_PKCS11 set. + +.. _modes_of_operation: + +`Modes of Operation <#modes_of_operation>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: + + The logger has several modes of operation: + + **1. Only display the sequence of PKCS #11 calls.** To enable this mode, set: + + .. code:: + + NSPR_LOG_MODULES=nss_mod_log:1 + NSPR_LOG_FILE=<logfile> + + The output format is: + + .. code:: + + OSThreadID[NSPRThreadID]: C_XXX + OSThreadID[NSPRThreadID]: rv = 0xYYYYYYYY + + For example, + + .. code:: + + 1024[805ef10]: C_Initialize + 1024[805ef10]: rv = 0x0 + 1024[805ef10]: C_GetInfo + 1024[805ef10]: rv = 0x0 + 1024[805ef10]: C_GetSlotList + 1024[805ef10]: rv = 0x0 + + **2. Display the sequence of PKCS #11 calls, and the parameters given to them.** To enable this + mode, set: + + .. code:: + + NSPR_LOG_MODULES=nss_mod_log:3 + NSPR_LOG_FILE=<logfile> + + The output format is: + + .. code:: + + OSThreadID[NSPRThreadID]: C_XXX + OSThreadID[NSPRThreadID]: arg1 = 0xAAAAAAAA + ... + OSThreadID[NSPRThreadID]: argN = 0xAAAAAAAA + OSThreadID[NSPRThreadID]: rv = 0xYYYYYYYY + + For example, + + .. code:: + + 1024[805ef10]: C_Initialize + 1024[805ef10]: pInitArgs = 0x4010c938 + 1024[805ef10]: rv = 0x0 + 1024[805ef10]: C_GetInfo + 1024[805ef10]: pInfo = 0xbffff340 + 1024[805ef10]: rv = 0x0 + 1024[805ef10]: C_GetSlotList + 1024[805ef10]: tokenPresent = 0x0 + 1024[805ef10]: pSlotList = 0x0 + 1024[805ef10]: pulCount = 0xbffff33c + 1024[805ef10]: *pulCount = 0x2 + 1024[805ef10]: rv = 0x0 + + Note that when a PKCS #11 function takes a pointer argument for which it will set a value + (C_GetSlotList above), this mode will display the value upon return. + + **3. Display verbose information, including template values, array values, etc.** To enable this + mode, set: + + .. code:: + + NSPR_LOG_MODULES=nss_mod_log:4 + NSPR_LOG_FILE=<logfile> + + The output format is the same as above, but with more information. For example, + + .. code:: + + 1024[805ef10]: C_FindObjectsInit + 1024[805ef10]: hSession = 0x1000001 + 1024[805ef10]: pTemplate = 0xbffff410 + 1024[805ef10]: ulCount = 3 + 1024[805ef10]: CKA_LABEL = localhost.nyc.rr.com [20] + 1024[805ef10]: CKA_TOKEN = CK_TRUE [1] + 1024[805ef10]: CKA_CLASS = CKO_CERTIFICATE [4] + 1024[805ef10]: rv = 0x0 + 1024[805ef10]: C_FindObjects + 1024[805ef10]: hSession = 0x1000001 + 1024[805ef10]: phObject = 0x806d810 + 1024[805ef10]: ulMaxObjectCount = 16 + 1024[805ef10]: pulObjectCount = 0xbffff38c + 1024[805ef10]: *pulObjectCount = 0x1 + 1024[805ef10]: phObject[0] = 0xf6457d04 + 1024[805ef10]: rv = 0x0 + 1024[805ef10]: C_FindObjectsFinal + 1024[805ef10]: hSession = 0x1000001 + 1024[805ef10]: rv = 0x0 + 1024[805ef10]: C_GetAttributeValue + 1024[805ef10]: hSession = 0x1000001 + 1024[805ef10]: hObject = 0xf6457d04 + 1024[805ef10]: pTemplate = 0xbffff2d0 + 1024[805ef10]: ulCount = 2 + 1024[805ef10]: CKA_TOKEN = 0 [1] + 1024[805ef10]: CKA_LABEL = 0 [20] + 1024[805ef10]: rv = 0x0 + 1024[805ef10]: C_GetAttributeValue + 1024[805ef10]: hSession = 0x1000001 + 1024[805ef10]: hObject = 0xf6457d04 + 1024[805ef10]: pTemplate = 0xbffff2d0 + 1024[805ef10]: ulCount = 2 + 1024[805ef10]: CKA_TOKEN = CK_TRUE [1] + 1024[805ef10]: CKA_LABEL = localhost.nyc.rr.com [20] + 1024[805ef10]: rv = 0x0 + + **4. Collect performance data.** This mode is most useful in optimized builds. The number of + calls to each PKCS #11 function will be counted, and the time spent in each function as well. A + summary of performance data is dumped during NSS shutdown. + + No additional environment variables are required for this mode. If the environment variable + NSS_OUTPUT_FILE is set, its value will be used as the path name of the file to which the final + output will be written. Otherwise, the output will be written to stdout.
\ No newline at end of file diff --git a/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note3/index.rst b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note3/index.rst new file mode 100644 index 0000000000..2d72c870cc --- /dev/null +++ b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note3/index.rst @@ -0,0 +1,234 @@ +.. _mozilla_projects_nss_nss_tech_notes_nss_tech_note3: + +nss tech note3 +============== + +.. _all_about_certificate_extensions: + +`All About Certificate Extensions <#all_about_certificate_extensions>`__ +------------------------------------------------------------------------ + +.. container:: + +.. _nss_technical_note_3: + +`NSS Technical Note: 3 <#nss_technical_note_3>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: + + .. code:: + + 09 May 2002 + Nelson B. Bolyard + + This week at least 5 different people came to me with variants of the + same question: + + What certificate extensions do I have to put into my cert for NSS to + allow it to be used for purpose <x>?? + + This message attempts to answer that question, and to document NSS's + approach to validating certificates for certain purposes. + + When NSS is asked to verify the validity of a certificate chain, it + verifies the validity of that cert chain for a particular purpose, + known as a SECCertUsage, as of a specific date and time. + + The list of known SECCertUsages is short: + + certUsageSSLClient ........... An SSL client authentication cert + certUsageSSLServer ........... An ordinary SSL server cert + certUsageSSLServerWithStepUp.. An SSL server cert that allows export + clients to use strong crypto. + certUsageSSLCA ............... An intermediate or root CA cert allowed + to issue SSL client or SSL server certs + or other intermediate SSL CA certs. + certUsageEmailSigner ......... Used to verify S/MIME email signatures + certUsageEmailRecipient ...... Used to encrypt S/MIME emails. + certUsageObjectSigner ........ Used to verify signatures on files of + executable code, e.g. jar files. + certUsageStatusResponder ..... Used by an OCSP responder + certUsageVerifyCA ............ A CA of any kind. + + Each cert has a "type" and a "key usage", each of which may contain one + or more valid values. + + Each of the above SECCertUsages translates into a required set of + cert type and key usage for the certificate itself, and into another + set of required cert type and key usage for all the CA certs in the + cert chain. + + To determine if a cert is valid for a given cert usage, it must have the + the cert type and key usage required for that cert usage, and all the + CA certs in the cert chain must have the cert type and key usage required + for CA certs for that cert usage. + + There are 8 Key Usages: + CERT_SIGN + CRL_SIGN + DATA_ENCIPHERMENT + DIGITAL_SIGNATURE + GOVT_APPROVED + KEY_AGREEMENT + KEY_ENCIPHERMENT + NON_REPUDIATION + + There are 9 Cert types: + EMAIL + EMAIL_CA + OBJECT_SIGNING + OBJECT_SIGNING_CA + SSL_CA + SSL_CLIENT + SSL_SERVER + STATUS_RESPONDER + TIME_STAMP + + + For the cert being checked, the requirements are: + + Cert Usage Requried Key Usage Required Cert Type + -------------------- -------------------- ----------------------- + SSLClient: DIGITAL_SIGNATURE; SSL_CLIENT; + + SSLServer: KEY_AGREEMENT OR + KEY_ENCIPHERMENT; SSL_SERVER; + + SSLServerWithStepUp: GOVT_APPROVED AND SSL_SERVER + KEY_AGREEMENT or + KEY_ENCIPHERMENT + + SSLCA: CERT_SIGN; SSL_CA; + + EmailSigner: DIGITAL_SIGNATURE; EMAIL; + + EmailRecipient: KEY_AGREEMENT OR + KEY_ENCIPHERMENT; EMAIL; + + ObjectSigner: DIGITAL_SIGNATURE; OBJECT_SIGNING; + + StatusResponder: DIGITAL_SIGNATURE; STATUS_RESPONDER; + + VerifyCA CERT_SIGN SSL_CA OR + EMAIL_CA OR + OBJECT_SIGNING_CA OR + STATUS_RESPONDER + + For CA certs in the cert chain, the requirements are: + + Cert Usage Requried Key Usage Required Cert Type + -------------------- -------------------- ----------------------- + SSLServerWithStepUp: GOVT_APPROVED AND + CERT_SIGN; SSL_CA; + + SSLClient: CERT_SIGN; SSL_CA; + + SSLServer: CERT_SIGN; SSL_CA; + + SSLCA: CERT_SIGN; SSL_CA; + + EmailSigner: CERT_SIGN; EMAIL_CA or SSL_CA + + EmailRecipient: CERT_SIGN; EMAIL_CA or SSL_CA + + ObjectSigner: CERT_SIGN; OBJECT_SIGNING_CA; + + UsageAnyCA: CERT_SIGN; OBJECT_SIGNING_CA OR + EMAIL_CA OR + SSL_CA; + + StatusResponder: CERT_SIGN; OBJECT_SIGNING_CA OR + EMAIL_CA OR + SSL_CA; + + Note: When the required key usage is KEY_AGREEMENT OR KEY_ENCIPHERMENT, + the actual key usage required depends on the key's algorithm. For + RSA keys, the required usage is KEY_ENCIPHERMENT. For other types of + keys, it is KEY_AGREEMENT. + + + Cert Extensions: + + One vital Certificate extension is the "Basic Constraints" extension. + It tells NSS whether the cert is a CA cert, or not, and affects every + other aspect of how the cert is interpreted by NSS. The OID for this + extension is { 2 5 29 19 }, encoded in hex as 0x55, 0x1d, 0x13. + If the extension is present and has the value TRUE, then this cert is + taken to be a CA cert. Otherwise it is not (except that trust flags + may override this, see discussion of trust flags farther below). + + Netscape has its own openly defined Cert Type extension, which can be used + to explicitly set the Cert Type in any Cert. The Cert Type extension has + bits in it that correspond directly to the cert types named above. + The OID for this extension is { 2 16 840 1 113730 1 1 } + encoded in hex as 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01 + + In addition to Netscape's own Cert Type extension, NSS recognizes various + X.509 extensions. + + The X.509 key usage extension has OID { 2 5 29 0F } encoded in hex as + 0x55, 0x1d, 0x0f. If present, this extension directly determines the + values of the 8 key usages defined above. If absent, the cert is + assumed to be valid for all key usages. + + The X.509v3 extended Key usage extension as OID { 2 5 29 37 } encoded in + hex as 0x55, 0x1d, 0x25. That extension contains a sequence of OIDs, each + of which signifies one or more Cert Types, depending on the presence or + absence of of the True Basic Constraints extension; that is, the + interpretation of the extended Key Usage extension is controlled by + whether the cert is a CA cert, or not. + + The following table shows the OIDs recognized in the extended key usage + extension, and how they map to cert types and key usages for CA and non-CA + certs. + + extended key usage OID non-CA cert CA cert + ----------------------------------- -------------- ---------------- + SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT EMAIL_CA EMAIL_CA + SEC_OID_EXT_KEY_USAGE_SERVER_AUTH SSL_SERVER SSL_CA + SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH SSL_CLIENT SSL_CA + SEC_OID_EXT_KEY_USAGE_CODE_SIGN OBJECT_SIGNING OBJECT_SIGNING_CA + SEC_OID_EXT_KEY_USAGE_TIME_STAMP TIME_STAMP TIME_STAMP + SEC_OID_OCSP_RESPONDER OCSP_RESPONDER OCSP_RESPONDER + + SEC_OID_NS_KEY_USAGE_GOVT_APPROVED GOVT_APPROVED GOVT_APPROVED + + If the extended key usage extension is absent, the cert is assumed to have + the cert types SSL_CLIENT, SSL_SERVER and EMAIL, and if the cert is a CA + cert (as indicated by the presence of a true basic constraints extension), + the cert is also assumed to have the cert types SSL_CA, EMAIL_CA and + STATUS_RESPONDER. If the basic constraints extension is missing, but the + user has trusted the cert as a CA cert, the cert also gets the + STATUS_RESPONDER cert type. If the cert has a Fortezza type public key + with the magic bits that signify that it is a CA, it is given cert types + SSL_CA and EMAIL_CA. + + A cert with the extended key usage extension and the Netscape cert type + extension that has the cert type SSL_CLIENT and also has an email address + in the subject is also given the cert type EMAIL. This allows all SSL + client authentication certs with email addresses to also be used as email + certs (provded they have adequate key usage). + + A cert with the extended key usage extension and the Netscape cert type + extension that as cert type SSL_CA is also always given cert type EMAIL_CA. + This allows all SSL intermediate CAs to also be used as email intermediate CAs. + + /* X.509 v3 Key Usage Extension flags */ + #define KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */ + #define KU_NON_REPUDIATION (0x40) /* bit 1 */ + #define KU_KEY_ENCIPHERMENT (0x20) /* bit 2 */ + #define KU_DATA_ENCIPHERMENT (0x10) /* bit 3 */ + #define KU_KEY_AGREEMENT (0x08) /* bit 4 */ + #define KU_KEY_CERT_SIGN (0x04) /* bit 5 */ + #define KU_CRL_SIGN (0x02) /* bit 6 */ + + #define NS_CERT_TYPE_SSL_CLIENT (0x80) /* bit 0 */ + #define NS_CERT_TYPE_SSL_SERVER (0x40) /* bit 1 */ + #define NS_CERT_TYPE_EMAIL (0x20) /* bit 2 */ + #define NS_CERT_TYPE_OBJECT_SIGNING (0x10) /* bit 3 */ + #define NS_CERT_TYPE_RESERVED (0x08) /* bit 4 */ + #define NS_CERT_TYPE_SSL_CA (0x04) /* bit 5 */ + #define NS_CERT_TYPE_EMAIL_CA (0x02) /* bit 6 */ + #define NS_CERT_TYPE_OBJECT_SIGNING_CA (0x01) /* bit 7 */ + </x>
\ No newline at end of file diff --git a/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note4/index.rst b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note4/index.rst new file mode 100644 index 0000000000..7a7334bee2 --- /dev/null +++ b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note4/index.rst @@ -0,0 +1,221 @@ +.. _mozilla_projects_nss_nss_tech_notes_nss_tech_note4: + +nss tech note4 +============== + +.. _pulling_certificate_extension_information_out_of_ssl_certificates: + +`Pulling certificate extension information out of SSL certificates <#pulling_certificate_extension_information_out_of_ssl_certificates>`__ +------------------------------------------------------------------------------------------------------------------------------------------ + +.. container:: + +.. _nss_technical_note_4: + +`NSS Technical Note: 4 <#nss_technical_note_4>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: + + **Note:** This document contains code snippets that focus on essential aspects of the task and + often do not illustrate all the cleanup that needs to be done. Also, this document does not + attempt to be an exhaustive survey of all possible ways to do a certain task; it merely tries to + show a certain way. + .. rubric:: Include these files + :name: include_these_files + + #include "ssl.h" + #include "cert.h" + .. rubric:: Get the handle of the cert associated with an SSL connection + :name: get_the_handle_of_the_cert_associated_with_an_ssl_connection + + *CERTCertificate\* cert = SSL_PeerCertificate(PRFileDesc \*fd);* + If SSL client, this will get you the server's cert handle; + If SSL server, this will get you the client's cert handle IF client auth is enabled + *CERTCertificate\* cert = SSL_LocalCertificate(PRFileDesc \*fd);* + If SSL client, this will get you the client cert's handle, IF client auth happened + If SSL server, this will get you the server's cert handle + .. rubric:: Don't forget to clean up the cert handle when you're done with it + :name: don't_forget_to_clean_up_the_cert_handle_when_you're_done_with_it + + *void CERT_DestroyCertificate(CERTCertificate \*cert);* + .. rubric:: Some info is readily available + :name: some_info_is_readily_available + + cert->subjectName (char*) + cert->issuerName (char*) + cert->emailAddr (char*) + OR char \*CERT_GetCertificateEmailAddress(CERTCertificate \*cert); + cert->keyUsage (unsigned int) + .. rubric:: To break the issuer and subject names into components + :name: to_break_the_issuer_and_subject_names_into_components + + Pass &(cert->issuer) or &(cert->subject) to the following functions + *char \*CERT_GetCommonName(CERTName \*name); + char \*CERT_GetCertEmailAddress(CERTName \*name); + char \*CERT_GetCountryName(CERTName \*name); + char \*CERT_GetLocalityName(CERTName \*name); + char \*CERT_GetStateName(CERTName \*name); + char \*CERT_GetOrgName(CERTName \*name); + char \*CERT_GetOrgUnitName(CERTName \*name); + char \*CERT_GetDomainComponentName(CERTName \*name); + char \*CERT_GetCertUid(CERTName \*name);* + + Example code to illustrate access to the info is given below. + .. rubric:: Background on cert extensions + :name: background_on_cert_extensions + + An extension has the following attributes + + - Object Id (OID) : A unique OID represents an algorithm, a mechanism, a piece of information, + etc. Examples: X500 RSA Encryption, Certificate Basic Constraints, PKCS#7 Digested Data, etc. + There is a long list of pre-defined OIDs, and new ones can be *added dynamically by an + application.* + The OID data structure contains an array of identifier bytes (each byte is a "level" in a + hierarchical namespace), a text description, and some other things. + - Critical : indicates whether the extension is critical + - Value : The value of the extension + + .. rubric:: Looping through all extensions + :name: looping_through_all_extensions + + *CERTCertExtension*\* extensions =cert->extensions;* + *if (extensions)* + *{* + * while (*extensions)* + * {* + * SECItem \*ext_oid = &(*extensions)->id;* + * SECItem \*ext_critical = &(*extensions)->critical;* + * SECItem \*ext_value = &(*extensions)->value;* + * /\* id attribute of the extension \*/* + * SECOidData \*oiddata = SECOID_FindOID(ext_oid);* + * if (oiddata == NULL)* + * {* + */\* OID not found \*/* + */\* SECItem ext_oid has type (SECItemType), data (unsigned char \*) and len (unsigned int) + fields* + * - the application interprets these \*/* + *.......* + * }* + * else* + * {* + *char \*name = oiddata->desc; /\* name of the extension \*/* + *.......* + * }* + * /\* critical attribute of the extension \*/* + * if (ext_critical->len > 0)* + * {* + *if (ext_critical->data[0])* + * /\* the extension is critical \*/* + *else* + * /\* the extension is not critical \*/* + * }* + * /\* value attribute of the extension \*/* + * /\* SECItem ext_value has type (SECItemType), data (unsigned char \*) and len + (unsigned int) fields* + *- the application interprets these \*/* + * SECOidTag oidtag = SECOID_FindOIDTag(ext_oid);* + * switch (oidtag)* + * {* + *case a_tag_that_app_recognizes:* + * .....* + *case .....* + * ......* + * }* + * extensions++;* + * }* + *}* + + .. rubric:: An example custom cert extension + :name: an_example_custom_cert_extension + + *struct \_myCertExtData* + *{* + * SECItem version;* + * SECItem streetaddress;* + * SECItem phonenum;* + * SECItem rfc822name;* + * SECItem id;* + * SECItem maxusers;* + *};* + *typedef struct \_myCertExtData myCertExtData;* + */\* template used for decoding the extension \*/* + *const SEC_ASN1Template myCertExtTemplate[] = {* + * { SEC_ASN1_SEQUENCE, 0, NULL, sizeof( myCertExtData ) },* + * { SEC_ASN1_INTEGER, offsetof(myCertExtData, version) },* + * { SEC_ASN1_OCTET_STRING, offsetof( myCertExtData, streetaddress ) },* + * { SEC_ASN1_OCTET_STRING, offsetof( myCertExtData, phonenum ) },* + * { SEC_ASN1_OCTET_STRING, offsetof( myCertExtData, rfc822name ) },* + * { SEC_ASN1_OCTET_STRING, offsetof( myCertExtData, id ) },* + * { SEC_ASN1_INTEGER, offsetof(myCertExtData, maxusers ) },* + * { 0 }* + *};* + */\* OID for my cert extension - replace 0xff with appropriate values*/* + *static const unsigned char myoid[] = { 0xff, 0xff, 0xff, 0xff, .... };* + *static const SECItem myoidItem = { (SECItemType) 0, (unsigned char \*)myoid, sizeof(myoid) + };* + *SECItem myextvalue; + myCertExtData data;* + *SECStatus rv = CERT_FindCertExtensionByOID(cert, &myoidItem, &myextvalue); + if (rv == SECSuccess) + { + SEC_ASN1DecoderContext \* context = SEC_ASN1DecoderStart(NULL, &data, myCertExtTemplate); + rv = SEC_ASN1DecoderUpdate( context, (const char \*)(myextvalue.data), myextvalue.len); + if (rv == SECSuccess) + { + /\* Now you can extract info from SECItem fields of your extension data structure \*/ + /\* See "Misc helper functions" below \*/ + ....... + /\* free the SECItem fields \*/ + SECITEM_FreeItem(&data.version, PR_FALSE); + SECITEM_FreeItem(&data.streetaddress, PR_FALSE); + ...... + SECITEM_FreeItem(&data.maxusers, PR_FALSE); + } + }* + + .. rubric:: Some miscellaneous helper functions + :name: some_miscellaneous_helper_functions + + - Compare two SECItems (e.g., two OIDs) + *PRBool SECITEM_ItemsAreEqual(const SECItem \*a, const SECItem \*b);* + - Interpreting a SECItem value as an integer + If SECItem \*item->len <=4, then int value = *DER_GetInteger(item)*; + - Interpreting a SECItem value as a string + Use string copy functions to copy item->len bytes from item->data and null terminate + explicitly + + .. rubric:: Some higher level extension functions + :name: some_higher_level_extension_functions + + - Get a specific extension from the list of extensions, given the extension tag + *SECStatus CERT_FindCertExtension (CERTCertificate \*cert, int tag, SECItem \*value);* + - Get a specific extension from the ISSUER's cert\ * + SECStatus CERT_FindIssuerCertExtension (CERTCertificate \*cert, int tag, SECItem \*value);* + - Get the value of an extension with the given OID + *SECStatus CERT_FindCertExtensionByOID (CERTCertificate \*cert, SECItem \*oid, SECItem + \*value);* + - Get the decoded value of the "Basic Constraints" extension + *SECStatus CERT_FindBasicConstraintExten (CERTCertificate \*cert, CERTBasicConstraints + \*value);* + - Get value of the keyUsage extension. This uses PR_Alloc to allocate buffer for the decoded + value, The caller should free up the storage allocated in value->data. + *SECStatus CERT_FindKeyUsageExtension (CERTCertificate \*cert, SECItem \*value);* + - Get decoded value of the subjectKeyID extension. This uses PR_Alloc to allocate buffer for + the decoded value, The caller should free up the storage allocated in value->data. + *SECStatus CERT_FindSubjectKeyIDExten (CERTCertificate \*cert, SECItem \*retItem);* + + * + * + +.. _for_more_information: + +`For more information <#for_more_information>`__ +------------------------------------------------ + +.. container:: + + - Browse through the NSS source code online at + http://lxr.mozilla.org/mozilla/source/security/nss/ and http://lxr.mozilla.org/security/ + - documentation on some cert funcs + `http://www.mozilla.org/projects/security/pki/nss/ref/ssl/sslcrt.html <https://www.mozilla.org/projects/security/pki/nss/ref/ssl/sslcrt.html>`__
\ No newline at end of file diff --git a/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note5/index.rst b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note5/index.rst new file mode 100644 index 0000000000..d9b7b9ddf6 --- /dev/null +++ b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note5/index.rst @@ -0,0 +1,659 @@ +.. _mozilla_projects_nss_nss_tech_notes_nss_tech_note5: + +nss tech note5 +============== + +.. _using_nss_to_perform_miscellaneous_cryptographic_operations: + +`Using NSS to perform miscellaneous cryptographic operations <#using_nss_to_perform_miscellaneous_cryptographic_operations>`__ +------------------------------------------------------------------------------------------------------------------------------ + +.. container:: + +.. _nss_technical_note_5: + +`NSS Technical Note: 5 <#nss_technical_note_5>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: + + - NSS Project Info is at + `http://www.mozilla.org/projects/security/pki/nss/ <https://www.mozilla.org/projects/security/pki/nss/>`__ + - You can browse the NSS source online at http://lxr.mozilla.org/mozilla/source/security/nss/ + and http://lxr.mozilla.org/security/ + - Be sure to look for :ref:`mozilla_projects_nss_sample_code` first for things you need to do. + - **Note:** This document contains code snippets that focus on essential aspects of the task and + often do not illustrate all the cleanup that needs to be done. Also, this document does not + attempt to be an exhaustive survey of all possible ways to do a certain task; it merely tries + to show a certain way. + + -------------- + +`Encrypt/Decrypt <#encryptdecrypt>`__ +------------------------------------- + +.. container:: + + #. Include headers + *#include "nss.h" + #include "pk11pub.h"* + #. Make sure NSS is initialized.The simplest Init function, in case you don't need a NSS database + is + *NSS_NoDB_Init(".")* + #. Choose a cipher mechanism. Note that some mechanisms (*_PAD) imply the padding is handled for + you by NSS. If you choose something else, then data padding is the application's + responsibility. You can find a list of cipher mechanisms in security/nss/lib/softoken/pkcs11.c + - grep for CKF_EN_DE_. + *CK_MECHANISM_TYPE cipherMech = CKM_DES_CBC_PAD* <big>(for example)</big> + #. Choose a slot on which to do the operation + *PK11SlotInfo\* slot = PK11_GetBestSlot(cipherMech, NULL); *\ **OR**\ * + PK11SlotInfo\* slot = PK11_GetInternalKeySlot(); /\* alwys returns internal slot, may not be + optimal \*/* + #. Prepare the Key + + - If using a raw key + */\* turn the raw key into a SECItem \*/ + SECItem keyItem; + keyItem.data = /\* ptr to an array of key bytes \*/ + keyItem.len = /\* length of the array of key bytes \*/ + /\* turn the SECItem into a key object \*/ + PK11SymKey\* SymKey = PK11_ImportSymKey(slot, cipherMech, PK11_OriginUnwrap, + + CKA_ENCRYPT, &keyItem, NULL)*; + - If generating the key - see section `Generate a Symmetric + Key <#generate_a_symmetric_key>`__ + + + #. <big>Prepare the parameter for crypto context. IV is relevant only when using CBC mode of + encryption. If not using CBC mode, just pass a NULL IV parm to PK11_ParamFromIV function + *SECItem ivItem; + ivItem.data = /\* ptr to an array of IV bytes \*/ + ivItem.len = /\* length of the array of IV bytes \*/ + SECItem \*SecParam = PK11_ParamFromIV(cipherMech, &ivItem);*\ </big> + #. <big>Now encrypt and decrypt using the key and parameter setup in above steps</big> + + - Create Encryption context + *PK11Context\* EncContext = PK11_CreateContextBySymKey(cipherMech, + + CKA_ENCRYPT or CKA_DECRYPT, + SymKey, + SecParam);* + - Do the Operation. If encrypting, outbuf len must be atleast (inbuflen + blocksize). If + decrypting, outbuflen must be atleast inbuflen. + *SECStatus s = PK11_CipherOp(EncContext, outbuf, &tmp1_outlen, sizeof outbuf, inbuf, + inbuflen); + s = PK11_DigestFinal(EncContext, outbuf+tmp1_outlen, &tmp2_outlen, + sizeof outbuf - tmp1_outlen); + result_len = tmp1_outlen + tmp2_outlen;* + - <big>Destroy the Context + *PK11_DestroyContext(EncContext, PR_TRUE);*\ </big> + + #. <big>Repeat Step 6 **any number of times**. When all done with encrypt/decrypt ops, clean + up</big> + <big>\ *PK11_FreeSymKey(SymKey); + SECITEM_FreeItem(SecParam, PR_TRUE); + PK11_FreeSlot(slot);*\ </big> + + | **Note:** AES encryption, a fixed blocksize of 16 bytes is used. The Rijndael algorithm permits + 3 blocksizes (16, 24, 32 bytes), but the AES standard requires the blocksize to be 16 bytes. + The keysize can vary and these keysizes are permitted: 16, 24, 32 bytes. + | You can also look at a `sample program <../sample-code/sample2.html>`__ illustrating encryption + + -------------- + +.. _hash_digest: + +`Hash / Digest <#hash_digest>`__ +-------------------------------- + +.. container:: + + #. Include headers + *#include "nss.h" + #include "pk11pub.h"* + #. Make sure NSS is initialized.The simplest Init function, in case you don't need a NSS database + is + *NSS_NoDB_Init(".")* + #. <big>Create Digest context</big>. Some of the digest algorithm identifiers are (without the + SEC_OID\_ prefix) : MD2, MD5, SHA1, SHA256, SHA384, SHA512. + *PK11Context\* DigestContext = PK11_CreateDigestContext(SEC_OID_MD5);* + #. <big>Digest the data</big> + <big>\ *SECStatus s = PK11_DigestBegin(DigestContext); + s = PK11_DigestOp(DigestContext, data, sizeof data); + s = PK11_DigestFinal(DigestContext, digest, &len, sizeof digest); + /\* now, digest contains the 'digest', and len contains the length of the digest \*/*\ </big> + #. Clean up + *PK11_DestroyContext(DigestContext, PR_TRUE);* + + | + | You can also look at a `sample program <../sample-code/sample3.html>`__ illustrating this + + -------------- + +.. _hash_digest_with_secret_key_included: + +`Hash / Digest with secret key included <#hash_digest_with_secret_key_included>`__ +---------------------------------------------------------------------------------- + +.. container:: + + #. Include headers + *#include "nss.h" + #include "pk11pub.h"* + #. Make sure NSS is initialized.The simplest Init function, in case you don't need a NSS database + is + *NSS_NoDB_Init(".")* + #. Choose a digest mechanism. You can find a list of digest mechanisms in + security/nss/lib/softoken/pkcs11.c - grep for CKF_DIGEST. + *CK_MECHANISM_TYPE digestMech = CKM_MD5* <big>(for example)</big> + #. Choose a slot on which to do the operation + *PK11SlotInfo\* slot = PK11_GetBestSlot(digestMech, NULL); *\ **OR**\ * + PK11SlotInfo\* slot = PK11_GetInternalKeySlot(); /\* always returns int slot, may not be + optimal \*/* + #. Prepare the Key + + - If using a raw key + */\* turn the raw key into a SECItem \*/ + SECItem keyItem; + keyItem.data = /\* ptr to an array of key bytes \*/ + keyItem.len = /\* length of the array of key bytes \*/ + /\* turn the SECItem into a key object \*/ + PK11SymKey\* SymKey = PK11_ImportSymKey(slot, digestMech, PK11_OriginUnwrap, + + CKA_DIGEST, &keyItem, NULL)*; + - If generating the key - see section `Generate a Symmetric + Key <#generate_a_symmetric_key>`__. Can use *CKM_GENERIC_SECRET_KEY_GEN* as the key gen + mechanism. + + + #. <big>Prepare the parameter for crypto context. The param must be provided, but can be empty. + *SECItem param; + param.data = 0; + param.len = 0;*\ </big> + #. <big>Create Crypto context</big> + *PK11Context\* DigestContext = PK11_CreateContextBySymKey(digestMech, CKA_DIGEST, SymKey, + + ¶m);* + #. <big>Digest the data</big>, providing the key + <big>\ *SECStatus s = PK11_DigestBegin(DigestContext); + s = PK11_DigestKey(DigestContext, SymKey); + s = PK11_DigestOp(DigestContext, data, sizeof data); + s = PK11_DigestFinal(DigestContext, digest, &len, sizeof digest); + /\* now, digest contains the 'digest', and len contains the length of the digest \*/*\ </big> + #. Clean up + *PK11_DestroyContext(DigestContext, PR_TRUE); + PK11_FreeSymKey(SymKey); + PK11_FreeSlot(slot);* + + You can also look at a `sample program <../sample-code/sample3.html>`__ illustrating this + + -------------- + +`HMAC <#hmac>`__ +---------------- + +.. container:: + + #. Include headers + *#include "nss.h" + #include "pk11pub.h"* + #. Make sure NSS is initialized.The simplest Init function, in case you don't need a NSS database + is + *NSS_NoDB_Init(".")* + #. Choose a HMAC mechanism. You can find a list of HMAC mechanisms in + security/nss/lib/softoken/pkcs11.c - grep for CKF_SN_VR, and choose the mechanisms that + contain HMAC in the name + *CK_MECHANISM_TYPE hmacMech = CKM_MD5_HMAC;* <big>(for example)</big> + #. Choose a slot on which to do the operation + *PK11SlotInfo\* slot = PK11_GetBestSlot(hmacMech, NULL); *\ **OR**\ * + PK11SlotInfo\* slot = PK11_GetInternalKeySlot(); /\* always returns int slot, may not be + optimal \*/* + #. Prepare the Key + + - If using a raw key + */\* turn the raw key into a SECItem \*/ + SECItem keyItem; + keyItem.type = siBuffer; + keyItem.data = /\* ptr to an array of key bytes \*/ + keyItem.len = /\* length of the array of key bytes \*/ + /\* turn the SECItem into a key object \*/ + PK11SymKey\* SymKey = PK11_ImportSymKey(slot, hmacMech, PK11_OriginUnwrap, + + CKA_SIGN, &keyItem, NULL)*; + - If generating the key - see section `Generate a Symmetric + Key <#generate_a_symmetric_key>`__. Can use *CKM_GENERIC_SECRET_KEY_GEN* as the key gen + mechanism. + + + #. <big>Prepare the parameter for crypto context. The param must be provided, but can be empty. + *SECItem param; + param.type = siBuffer; + param.data = NULL; + param.len = 0;*\ </big> + #. <big>Create Crypto context</big> + *PK11Context\* DigestContext = PK11_CreateContextBySymKey(hmacMech, CKA_SIGN, + + SymKey, ¶m);* + #. <big>Digest the data</big> + <big>\ *SECStatus s = PK11_DigestBegin(DigestContext); + s = PK11_DigestOp(DigestContext, data, sizeof data); + s = PK11_DigestFinal(DigestContext, digest, &len, sizeof digest); + /\* now, digest contains the 'signed digest', and len contains the length of the digest + \*/*\ </big> + #. Clean up + *PK11_DestroyContext(DigestContext, PR_TRUE);* + *PK11_FreeSymKey(SymKey); + PK11_FreeSlot(slot);* + + | + | You can also look at a `sample program <../sample-code/sample3.html>`__ illustrating this + + -------------- + +.. _symmetric_key_wrappingunwrapping_of_a_symmetric_key: + +`Symmetric Key Wrapping/Unwrapping of a Symmetric Key <#symmetric_key_wrappingunwrapping_of_a_symmetric_key>`__ +--------------------------------------------------------------------------------------------------------------- + +.. container:: + + #. Include headers + *#include "nss.h" + #include "pk11pub.h"* + #. Make sure NSS is initialized.The simplest Init function, in case you don't need a NSS database + is + *NSS_NoDB_Init(".")* + #. Choose a Wrapping mechanism. See wrapMechanismList in security/nss/lib/pk11wrap/pk11slot.c + and security/nss/lib/ssl/ssl3con.c for examples of wrapping mechanisms. Most of them are + cipher mechanisms. + *CK_MECHANISM_TYPE wrapMech = CKM_DES3_ECB;* <big>(for example)</big> + #. Choose a slot on which to do the operation + *PK11SlotInfo\* slot = PK11_GetBestSlot(wrapMech, NULL); *\ **OR**\ * + PK11SlotInfo\* slot = PK11_GetInternalKeySlot(); /\* always returns int slot, may not be + optimal \*/* + <big>Regarding the choice of slot and wrapMech, if you know one, you can derive the other. You + can get the best slot given a wrap mechanism (as shown above), or get the best wrap mechanism + given a slot using:</big> + *CK_MECHANISM_TYPE wrapMech = PK11_GetBestWrapMechanism(slot)* + #. Prepare the Wrapping Key + + - If using a raw key + */\* turn the raw key into a SECItem \*/ + SECItem keyItem; + keyItem.data = /\* ptr to an array of key bytes \*/ + keyItem.len = /\* length of the array of key bytes \*/ + /\* turn the SECItem into a key object \*/ + PK11SymKey\* WrappingSymKey = PK11_ImportSymKey(slot, wrapMech, + + PK11_OriginUnwrap, + + CKA_WRAP, &keyItem, NULL)* + + - If generating the key - see section `Generate a Symmetric + Key <#generate_a_symmetric_key>`__ + + + #. Prepare the To-be-Wrapped Key + + - If using a raw key + */\* turn the raw key into a SECItem \*/ + SECItem keyItem; + keyItem.data = /\* ptr to an array of key bytes \*/ + keyItem.len = /\* length of the array of key bytes \*/ + /\* turn the SECItem into a key object \*/ + PK11SymKey\* ToBeWrappedSymKey = PK11_ImportSymKey(slot, wrapMech,, + + PK11_OriginUnwrap, + + CKA_WRAP, &keyItem, NULL)*; + - If generating the key - see section `Generate a Symmetric + Key <#generate_a_symmetric_key>`__ + + + #. <big>Prepare the parameter for crypto context. IV is relevant only when using CBC cipher mode. + If not using CBC mode, just pass a NULL *SecParam* to *PK11_WrapSymKey* or *PK11_UnwrapSymKey* + function + *SECItem ivItem; + ivItem.data = /\* ptr to an array of IV bytes \*/ + ivItem.len = /\* length of the array of IV bytes \*/ + SECItem \*SecParam = PK11_ParamFromIV(wrapMech, &ivItem);*\ </big> + #. Allocate space for the wrapped key + *SECItem WrappedKey; + WrappedKey.len = SOME_LEN; + WrappedKey.data = allocate (SOME_LEN) bytes;* + #. <big>Do the Wrap</big>. Note that the WrappingSymKey and the ToBeWrappedSymKey must be on the + slot where the wrap is going to happen. To move keys to the desired slot, see section `Moving + a Key from one slot to another <#moving_a_key_from_one_slot_to_another>`__ + <big>\ *SECStatus s = PK11_WrapSymKey(wrapMech, SecParam, WrappingSymKey, + ToBeWrappedSymKey, + &WrappedKey);*\ </big> + #. <big><big>Transport/Store or do whatever with the Wrapped Key (WrappedKey.data, + WrappedKey.len)</big></big> + #. <big><big>Unwrapping. </big></big> + + - <big><big>Set up the args to the function *PK11_UnwrapSymKey*, most of which are + illustrated above. The *keyTypeMech* arg of type *CK_MECHANISM_TYPE *\ <big>indicates the + type of key that was wrapped and can be same as the *wrapMech* (e.g. + *wrapMech=CKM_SKIPJACK_WRAP, keyTypeMech=CKM_SKIPJACK_CBC64; wrapMech=CKM_SKIPJACK_CBC64, + keyTypeMech=CKM_SKIPJACK_CBC64*).</big>\ </big></big> + - Do the unwrap + <big><big>\ *PK11SymKey\* UnwrappedSymKey = PK11_UnwrapSymKey(WrappingSymKey, + + wrapMech*\ </big></big><big><big>\ *, SecParam, &WrappedKey, + + keyTypeMech,*\ </big></big> + <big><big>\ * + CKA_UNWRAP, /\* or CKA_DECRYPT? \*/ + + size_of_key_that_was_wrapped_bytes);*\ </big></big> + + #. Clean up + *PK11_FreeSymKey(WrappingSymKey);* + *PK11_FreeSymKey(ToBeWrappedSymKey); + PK11_FreeSymKey(UnwrappedSymKey); + if (SecParam) SECITEM_FreeItem(SecParam, PR_TRUE); + SECITEM_FreeItem(&WrappedKey, PR_TRUE); + PK11_FreeSlot(slot); * + + -------------- + +.. _symmetric_key_wrappingunwrapping_of_a_private_key: + +`Symmetric Key Wrapping/Unwrapping of a Private Key <#symmetric_key_wrappingunwrapping_of_a_private_key>`__ +----------------------------------------------------------------------------------------------------------- + +.. container:: + + #. Include headers + *#include "nss.h" + #include "pk11pub.h"* + #. Make sure NSS is initialized. + #. Choose a Wrapping mechanism. See wrapMechanismList in security/nss/lib/pk11wrap/pk11slot.c + and security/nss/lib/ssl/ssl3con.c for examples of wrapping mechanisms. Most of them are + cipher mechanisms. + *CK_MECHANISM_TYPE wrapMech = CKM_DES3_ECB;* <big>(for example).</big> + #. Slot on which to do the operation + *PK11SlotInfo\* slot = PK11_GetBestSlot(wrapMech, NULL); *\ **OR**\ * + PK11SlotInfo\* slot = PK11_GetInternalKeySlot(); /\* always returns int slot, may not be + optimal \*/* + This should be the slot that is best suited for the wrapping. This may or may not be the slot + that contains the private key or the slot that contains the Symmetric key. + <big>Regarding the choice of slot and wrapMech, if you know one, you can derive the other. You + can get the best slot given a wrap mechanism (as shown above), or get the best wrap mechanism + given a slot using:</big> + *CK_MECHANISM_TYPE wrapMech = PK11_GetBestWrapMechanism(slot)* + #. Prepare the Wrapping Key + + - If using a raw key + */\* turn the raw key into a SECItem \*/ + SECItem keyItem; + keyItem.data = /\* ptr to an array of key bytes \*/ + keyItem.len = /\* length of the array of key bytes \*/ + /\* turn the SECItem into a key object \*/ + PK11SymKey\* WrappingSymKey = PK11_ImportSymKey(slot, wrapMech, + + PK11_OriginUnwrap, + + CKA_WRAP, &keyItem, NULL)*; + - If generating the key - see section `Generate a Symmetric + Key <#generate_a_symmetric_key>`__ + + + #. Prepare the To-be-Wrapped Key + + - *SECKEYPrivateKey \*ToBeWrappedPrivKey * + + #. <big>Prepare the parameter for crypto context. IV is relevant only when using CBC cipher mode. + If not using CBC mode, just pass a NULL *SecParam* to *PK11_WrapPrivKey* function + *SECItem ivItem; + ivItem.data = /\* ptr to an array of IV bytes \*/ + ivItem.len = /\* length of the array of IV bytes \*/ + SECItem \*SecParam = PK11_ParamFromIV(wrapMech, &ivItem);*\ </big> + #. Allocate space for the wrapped key. Note that a 2048-bit *wrapped* RSA private key takes up + around 1200 bytes. + *SECItem WrappedKey; + WrappedKey.len = SOME_LEN; + WrappedKey.data = allocate (SOME_LEN) bytes;* + #. <big>Do the Wrap</big>. Note that the WrappingSymKey and the ToBeWrappedPvtKey must be on the + slot where the wrap is going to happen. To move keys to the desired slot, see section `Moving + a Key from one slot to another <#moving_a_key_from_one_slot_to_another>`__ + <big>\ *SECStatus s = PK11_WrapPrivKey(slot, WrappingSymKey, ToBeWrappedPvtKey, wrapMech, + SecParam, &WrappedKey, + NULL);*\ </big> + #. <big><big>Transport/Store or do whatever with the Wrapped Key (WrappedKey.data, + WrappedKey.len)</big></big> + #. <big><big>Unwrapping.</big></big> + + - Prepare the args for the unwrap function. Most of the args are illustrated above + *SECItem label; /\* empty, doesn't need to be freed \*/ + label.data = NULL; label.len = 0;* + *SECItem \*pubValue = NULL; + pubValue = /\* ?? \*/;* + *PRBool token = /\* PR_TRUE or PR_FALSE depending on?? \*/ + CK_MECHANISM_TYPE keyTypeMech = ??; + CK_KEY_TYPE keyType; + keyType = PK11_GetKeyType(keyTypeMech, 0); + CK_ATTRIBUTE_TYPE attribs[4]; + int numAttribs; + /\* figure out which operations to enable for this key \*/ + if( keyType == CKK_RSA ) { + attribs[0] = CKA_SIGN; + attribs[1] = CKA_DECRYPT; + attribs[2] = CKA_SIGN_RECOVER; + attribs[3] = CKA_UNWRAP; + numAttribs = 4; + } else if(keyType == CKK_DSA) { + attribs[0] = CKA_SIGN; + numAttribs = 1; + }* + - <big>Do the unwrap</big> + *SECKEYPrivateKey \*UnwrappedPvtKey = + PK11_UnwrapPrivKey(slot, WrappingSymKey, wrapMech, SecParam, &WrappedKey, + &label, pubValue, token, PR_TRUE + /\* sensitive \*/ + keyType, attribs, numAttribs, + NULL /*wincx*/);* + + #. Clean up + *PK11_FreeSymKey(WrappingSymKey);* + <big>\ *if (SecParam) SECITEM_FreeItem(SecParam, PR_TRUE);*\ </big> + <big>\ *SECITEM_FreeItem(&WrappedKey, PR_TRUE);*\ </big> + *if (pubValue) SECITEM_FreeItem(pubValue, PR_TRUE);* + *if (UnwrappedPvtKey) SECKEY_DestroyPrivateKey(UnwrappedPvtKey);* + *if (ToBeWrappedPvtKey) SECKEY_DestroyPrivateKey(ToBeWrappedPvtKey);* + *PK11_FreeSlot(slot);* + + -------------- + +.. _public_key_wrapping_private_key_unwrapping_of_a_symmetric_key_(pki_based_key_transport): + +`Public Key Wrapping & Private Key Unwrapping of a Symmetric Key (PKI based key transport) <#public_key_wrapping_private_key_unwrapping_of_a_symmetric_key_(pki_based_key_transport)>`__ +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +.. container:: + + #. Include headers + *#include "nss.h" + #include "pk11pub.h"* + #. Make sure NSS is initialized. + #. Choose a Wrapping mechanism. See wrapMechanismList in security/nss/lib/pk11wrap/pk11slot.c + and security/nss/lib/ssl/ssl3con.c for examples of wrapping mechanisms. Most of them are + cipher mechanisms. + *CK_MECHANISM_TYPE wrapMech = CKM_DES3_ECB;* <big>(for example)</big> + #. Slot on which to do the operation + *PK11SlotInfo\* slot = PK11_GetBestSlot(wrapMech, NULL); *\ **OR**\ * + PK11SlotInfo\* slot = PK11_GetInternalKeySlot(); /\* always returns int slot, may not be + optimal \*/* + This should be the slot that is best suited for the wrapping. This may or may not be the slot + that contains the public/private key or the slot that contains the Symmetric key. + <big>Regarding the choice of slot and wrapMech, if you know one, you can derive the other. You + can get the best slot given a wrap mechanism (as shown above), or get the best wrap mechanism + given a slot using:</big> + *CK_MECHANISM_TYPE wrapMech = PK11_GetBestWrapMechanism(slot)* + #. Prepare the Wrapping Key + + - *SECKeyPublicKey \*WrappingPubKey* + + #. Prepare the To-be-Wrapped Key + + - If using a raw key + */\* turn the raw key into a SECItem \*/ + SECItem keyItem; + keyItem.data = /\* ptr to an array of key bytes \*/ + keyItem.len = /\* length of the array of key bytes \*/ + /\* turn the SECItem into a key object \*/ + PK11SymKey\* ToBeWrappedSymKey = PK11_ImportSymKey(slot, wrapMech,, + + PK11_OriginUnwrap, + + CKA_WRAP, &keyItem, NULL)*; + - If generating the key - see section `Generate a Symmetric + Key <#generate_a_symmetric_key>`__ + + #. Allocate space for the wrapped key + *SECItem WrappedKey; + WrappedKey.len = SOME_LEN; + WrappedKey.data = allocate (SOME_LEN) bytes;* + #. <big>Do the Wrap</big>. Note that the WrappingPubKey and the ToBeWrappedSymKey must be on the + slot where the wrap is going to happen. To move keys to the desired slot, see section `Moving + a Key from one slot to another <#moving_a_key_from_one_slot_to_another>`__ + <big>\ *SECStatus s = PK11_PubWrapSymKey(wrapMech, WrappingPubKey, + ToBeWrappedSymKey, + &WrappedKey);*\ </big> + #. <big><big>Transport/Store or do whatever with the Wrapped Key (WrappedKey.data, + WrappedKey.len)</big></big> + #. <big><big>Unwrapping. </big></big> + + - Prepare the args for the unwrap function. Most of the args are illustrated above + *SECKEYPrivateKey \*UnWrappingPvtKey; + CK_MECHANISM_TYPE keyTypeMech = ??;* + - <big>Do the unwrap</big> + *PK11SymKey \*UnwrappedSymKey = + PK11_PubUnwrapSymKey(UnWrappingPvtKey, WrappedKey, keyTypeMech, + *<big><big>\ *CKA_UNWRAP, /\* + or CKA_DECRYPT? \*/ + + *\ </big></big><big><big>\ *size_of_key_that_was_wrapped_bytes);*\ </big></big> + + #. Clean up + *PK11_FreeSymKey(ToBeWrappedSymKey);* + <big>\ *SECITEM_FreeItem(&WrappedKey, PR_TRUE);*\ </big> + *if (WrappingPubKey) SECKEY_DestroyPublicKey(WrappingPubKey);* + *if (UnwrappingPvtKey) SECKEY_DestroyPrivateKey(UnwrappingPvtKey);* + *PK11_FreeSlot(slot);* + + Also look at a `sample program <../sample-code/sample1.html>`__ that uses the above functions. + + -------------- + +.. _generate_a_symmetric_key_2: + +`Generate a Symmetric Key <#generate_a_symmetric_key_2>`__ +---------------------------------------------------------- + +.. container:: + + | Subsequent to the operation, the symmetric key may need to be transported/stored in wrapped or + raw form. You can find a list of key generation mechanisms in + security/nss/lib/softoken/pkcs11.c - grep for CKF_GENERATE. For some key gen mechanisms, the + keysize is in bytes, and for some it is in bits. + | + + #. <big>Choose a key generation mechanism</big> + *CK_MECHANISM_TYPE keygenMech = CKM_DES_KEY_GEN;* (for example) + #. <big>Generate the key</big> + *PK11SymKey\* SymKey = PK11_KeyGen(slot, keygenMech, NULL, keysize, NULL);* + + <big>You can also see an `sample program <../sample-code/sample1.html>`__ that does key + generation.</big> + + .. rubric:: Extract the raw key (This should not normally be used. Better to use wrapping + instead. See `method1 <#symmetric_key_wrappingunwrapping_sym_key>`__ and + `method2 <#pki_wrap_symkey>`__ ). + :name: extract_the_raw_key_(this_should_not_normally_be_used._better_to_use_wrapping_instead._see_method1_and_method2_). + + *SECStatus rv = PK11_ExtractKeyValue(SymKey); + SECItem \*keydata = PK11_GetKeyData(SymKey);* + + .. rubric:: Generating a persistent symmetric key + :name: generating_a_persistent_symmetric_key + + | *SECItem keyid; + CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC_PAD; + keyid.data = /\* ptr to an array of bytes representing the id of the key to be generated \*/; + keyid.len = /\* length of the array of bytes \*/; + /\* keysize must be 0 for fixed key-length algorithms like DES... and appropriate value + \* for non fixed-key-length algorithms \*/ + PK11SymKey \*key = PK11_TokenKeyGen(slot, cipherMech, 0, 32 /\* keysize \*/, + &keyid, PR_TRUE, + 0);* + | *int keylen = PK11_GetKeyLength(key); + cipherMech = PK11_GetMechanism(key);* + | */\* find the symmetric key in the database \*/ + key = PK11_FindFixedKey(slot, cipherMech, &keyid, 0);* + + -------------- + +.. _moving_a_key_from_one_slot_to_another_2: + +`Moving a Key from one slot to another <#moving_a_key_from_one_slot_to_another_2>`__ +------------------------------------------------------------------------------------ + +.. container:: + + - To move a Private key from one slot to another, wrap the private key on the origin slot and + unwrap it into the destination slot. See section `Symmetric Key Wrapping/Unwrapping of a + Private Key <#symmetric_key_wrappingunwrapping_pvtkey>`__ + - To move a Symmetric key + *PK11SymKey \*destSymKey = pk11_CopyToSlot(destslot, wrapMech, CKA_UNWRAP?, origSymKey);* + + -------------- + +.. _generate_an_rsa_key_pair: + +`Generate an RSA Key Pair <#generate_an_rsa_key_pair>`__ +-------------------------------------------------------- + +.. container:: + + *PK11_GenerateKeyPair*\ <big> is the function to use</big>. See a `sample + program <../sample-code/sample1.html>`__ that uses this function. + + -------------- + +.. _<big>sign_verify_data<big>: + +`<big>Sign & Verify Data</big> <#%3Cbig%3Esign_verify_data%3Cbig%3E>`__ +----------------------------------------------------------------------- + +.. container:: + + | *SECKEYPrivateKey \*pvtkey; + SECItem signature; + SECItem data; + SECStatus s = PK11_Sign(pvtkey, &signature, &data);* + | *SECKeyPublicKey \*pubkey;* + | *SECStatus s = PK11_Verify(pubkey, &signature, &data, NULL);* + + -------------- + +.. _misc_useful_functions: + +`Misc Useful Functions <#misc_useful_functions>`__ +-------------------------------------------------- + +.. container:: + + #. Get the best wrapping mechanism supported by a slot + *CK_MECHANISM_TYPE mech = PK11_GetBestWrapMechanism(PK11SlotInfo \*slot);* + #. <big>Get the best slot for a certain mechanism</big> + *PK11SlotInfo\* slot = PK11_GetBestSlot(mechanism, NULL);* + #. <big>Get the best key length for a certain mechanism on a given slot</big> + *int keylen = PK11_GetBestKeyLength(PK11SlotInfo \*slot, mechanism);* + #. Get the key length of a symmetric key + *int keylen = PK11_GetKeyLength(PK11SymKey \*symkey);* + #. Get the mechanism given a symmetric key + *CK_MECHANISM_TYPE mech = PK11_GetMechanism(PK11SymKey \*key);* + + + --------------
\ No newline at end of file diff --git a/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note6/index.rst b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note6/index.rst new file mode 100644 index 0000000000..a55425c752 --- /dev/null +++ b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note6/index.rst @@ -0,0 +1,104 @@ +.. _mozilla_projects_nss_nss_tech_notes_nss_tech_note6: + +nss tech note6 +============== + +.. _nss_.chk_files_for_the_fips_140_mode: + +`NSS .chk Files for the FIPS 140 Mode + <#nss_.chk_files_for_the_fips_140_mode>`__ +------------------------------------------- + +.. container:: + +.. _nss_technical_note_6: + +`NSS Technical Note: 6 <#nss_technical_note_6>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: + + In NSS 3.8, we added checksum files required for the NSS softoken to operate in FIPS 140 mode. + The new checksum file is called libsoftokn3.chk on Unix/Linux and softokn3.chk on Windows. It + must be put in the same directory as the NSS libraries. The libsoftokn3.chk/softokn3.chk file + contains a checksum for the softoken. When in FIPS 140 mode, the softoken is required to compute + its checksum and compare it with the value in libsoftokn3.chk/softokn3.chk. + + The following applies to NSS 3.8 through 3.10 : + + | On 32-bit Solaris SPARC (i.e., not x86, and not 64-bit SPARC) and 32-bit HP-UX PA-RISC (i.e., + not Itanium, and not 64-bit PA-RISC), there are two more .chk files: libfreebl_pure32_3.chk and + libfreebl_hybrid_3.chk. + | + + The following applies to NSS 3.11 : + + The low-level freebl cryptographic code has been separated from softoken on all platforms. Even + on platforms for which there is only one implementation of freebl, there is now a separate freebl + shared library. The freebl library implements a private interface internal to NSS. + + - On 32-bit Windows and 32-bit OS/2, this shared library is called freebl3.dll, and the + corresponding .chk file is called freebl3.chk . + - On 32-bit Solaris x86, 64-bit Solaris x64 (AMD64), 32-bit Linux x86, 64-bit Linux x86-64, + 32-bit AIX and 64-bit AIX, this shared library is called libfreebl3.so, and the corresponding + .chk file is called libfreebl3.chk . + - On the 32-bit Solaris SPARC architecture, there are 3 freebl libraries : + + - libfreebl_32int64_3.so for UltraSparc T1 CPUs, with a corresponding libfreebl_32int64_3.chk + - libfreebl_32fpu_3.so for other UltraSparc CPUs, with a corresponding libfreebl_32fpu_3.chk + - libfreebl_32int_3.so for SPARC V8 CPUs, with a corresponding libfreebl_32int_3.chk + + - On the 64-bit Solaris SPARC architecture, there are 2 freebl libraries : + + - libfreebl_64int_3.so for UltraSparc T1 CPUs, with a corresponding libfreebl_64int_3.chk + - libfreebl_64fpu_3.so for other UltraSparc CPUs, with a corresponding libfreebl_64fpu_3.chk + + - On the 32-bit HP-UX PA-RISC architecture, there are 2 freebl libraries : + + - libfreebl_32fpu_3.sl for CPUs that do multiply operations faster in floating point, with a + corresponding libfreebl_32fpu_3.chk + - libfreebl_32int_3.sl for other PA-RISC CPUs, with a corresponding libfreebl_32int_3.chk + + - On the 64-bit HP-UX PA-RISC architecture, there is only one freebl library, called + libfreebl3.sl, with a corresponding libfreebl3.chk + + Applications should always use NSS binaries that are the output of the regular NSS build process. + If your application modifies NSS binaries for any reason after they were built, then : + + - The FIPS 140 mode of operation will no longer work, because the chk files will no longer match + the softoken and freebl shared libraries . + - The softoken and freebl binaries won't match any NSS binaries that may have been submitted to + NIST for validation, and thus may not be verified as being the actual FIPS 140 validated + cryptographic module . The only way to meet this requirement is for your application never to + modify the NSS binaries. + - Any offer of binary support that may have been previously made to you by NSS developers is + null and void. + + If your build process modifies NSS libraries in any way (for example, to strip the symbols), it + should consider not doing so for the reasons cited above. If you still decide to make unsupported + changes, you can allow the softoken to come up in FIPS 140 mode of operation by regenerating the + .chk files yourself. The tool to do that is called shlibsign. It is released as part of the NSS + binary distributions. + If your build process does not modify NSS shared libraries, you can just use the .chk files in + the NSS binary distributions. + + So you have two options. + + 1. Do not modify NSS libraries in your build process. Specifically, do not modify libsoftokn3.so, + libsoftokn3.sl, softokn3.dll, libfreebl_pure32_3.so, libfreebl_pure32_3.sl, + libfreebl_hybrid_3.so,libfreebl_hybrid_3.sl, libfreebl3.so, libfreebl3.sl, freebl3.dll, + libfreebl_32int64_3.so, libfreebl_32int_3.so, libfreebl_32fpu_3.so, libfreebl_64int_3.so, + libfreebl_64fpu_3.so, libfreebl_32int_3.sl, libfreebl_32fpu_3.sl; or + + 2. Use shlibsign to regenerate the .chk files. For example, on 32-bit Solaris SPARC for NSS + 3.11, say + + shlibsign -v -i libsoftokn3.so + shlibsign -v -i libfreebl_32int64_3.so + shlibsign -v -i libfreebl_32fpu_3.so + shlibsign -v -i libfreebl_32int_3.so + + (You need to set LD_LIBRARY_PATH appropriately and specify the correct pathnames of the + libraries.) + + Option 1 is simpler and highly preferred.
\ No newline at end of file diff --git a/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note7/index.rst b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note7/index.rst new file mode 100644 index 0000000000..f7fa00f6d9 --- /dev/null +++ b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note7/index.rst @@ -0,0 +1,189 @@ +.. _mozilla_projects_nss_nss_tech_notes_nss_tech_note7: + +nss tech note7 +============== + +.. _rsa_signing_and_encryption_with_nss: + +`RSA Signing and Encryption with NSS <#rsa_signing_and_encryption_with_nss>`__ +------------------------------------------------------------------------------ + +.. container:: + +.. _nss_technical_note_7: + +`NSS Technical Note: 7 <#nss_technical_note_7>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: + + This technical note explains how to use NSS to perform RSA signing and encryption. The industry + standard for RSA signing and encryption is `PKCS + #1 <http://www.rsasecurity.com/rsalabs/node.asp?id=2125>`__. NSS supports PKCS #1 v1.5. NSS + doesn't yet support PKCS #1 v2.0 and v2.1, in particular OAEP, but OAEP support is on our `to-do + list <https://bugzilla.mozilla.org/show_bug.cgi?id=158747>`__. Your contribution is welcome. + +.. _data_types: + +`Data Types <#data_types>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: + + NSS uses the following data types to represent keys: + + - ``SECKEYPublicKey``: a public key, defined in "keythi.h". + - ``SECKEYPrivateKey``: a private key, defined in "keythi.h". + - ``PK11SymKey``: a symmetric key (often called a session key), defined in "secmodt.h". + + | These data types should be used as if they were opaque structures, that is, they should only be + created by some NSS functions and you always pass pointers to these data types to NSS functions + and never examine the members of these structures. + | The strength of an RSA key pair is measured by the size of its modulus because given the + modulus and public exponent, the best known algorithm for computing the private exponent is to + factor the modulus. At present 1024 bit and 2048 bit RSA keys are the most common and + recommended. To prevent denial-of-service attacks with huge public keys, NSS disallows modulus + size greater than 8192 bits. + | How are these keys created in NSS? There are a few possibilities. + + - RSA key pairs may be generated inside a crypto module (also known as a token). Use + ``PK11_GenerateKeyPair()`` to generate a key pair in a crypto module. + + - Key pairs may be generated elsewhere, exported in encrypted form, and imported into a crypto + module. + + - | Public keys may be imported into NSS. Call ``SECKEY_ImportDERPublicKey()`` with + ``type=CKK_RSA`` to import a DER-encoded RSA public key. If you have the modulus and public + exponent, you need to first encode them into an RSA public key and then import the public + key into NSS. + | PKCS #1 defines an RSA public key as a ``SEQUENCE`` of modulus and public exponent, both of + which are ``INTEGER``\ s. Here is the ASN.1 type definition: + + .. code:: + + RSAPublicKey ::= SEQUENCE { + modulus INTEGER, -- n + publicExponent INTEGER -- e } + + The following sample code (error handling omitted for brevity) encodes a ``RSAPublicKey`` from + a modulus and a public exponent and imports the public key into NSS. + + .. code:: + + struct MyRSAPublicKey { + SECItem m_modulus; + SECItem m_exponent; + } inPubKey; + + SECItem derPubKey; + + SECKEYPublicKey *pubKey; + + const SEC_ASN1Template MyRSAPublicKeyTemplate[] = { + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(MyRSAPublicKey) }, + { SEC_ASN1_INTEGER, offsetof(MyRSAPublicKey,m_modulus), }, + { SEC_ASN1_INTEGER, offsetof(MyRSAPublicKey,m_exponent), }, + { 0, } + }; + + PRArenaPool *arena; + + /* + * Point inPubKey.m_modulus and m_exponent at the data, and + * then set their types to unsigned integers. + */ + inPubKey.m_modulus.type = siUnsignedInteger; + inPubKey.m_exponent.type = siUnsignedInteger; + + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + SEC_ASN1EncodeItem(arena, &derPubKey, &inPubKey, + MyRSAPublicKeyTemplate); + pubKey = SECKEY_ImportDERPublicKey(&derPubKey, CKK_RSA); + PORT_FreeArena(arena, PR_FALSE); + + - Public keys may be extracted from certificates. Given a certficate (``CERTCertificate *``), + use ``CERT_ExtractPublicKey()`` to extract its public key. The returned public key may be used + after the certificate is destroyed. + + When the keys are no longer needed, they need to be destroyed. + + - Use ``SECKEY_DestroyPublicKey()`` to destroy a public key (``SECKEYPublicKey *``). + - Use ``SECKEY_DestroyPrivateKey()`` to destroy a private key (``SECKEYPrivateKey *``). + - Unlike ``SECKEYPublicKey`` and ``SECKEYPrivateKey``, ``PK11SymKey`` objects are reference + counted. Use ``PK11_ReferenceSymKey()`` to acquire a reference to a symmetric key + (``PK11SymKey *``). Use ``PK11_FreeSymKey()`` to release a reference to a symmetric key + (``PK11SymKey *``); the symmetric key is destroyed when its reference count becomes zero. + +`Functions <#functions>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: + + | RSA signing and encryption functions are provided by two layers of NSS function: the ``SGN_`` + and ``VFY_`` functions in cryptohi.h, and the ``PK11_`` functions in pk11pub.h. As a general + principle, you should use the highest layer of NSS you can possibly use for what you are trying + to accomplish. + | For example, if you just need to generate or verify a signature, you can use the ``SGN_`` and + ``VFY_`` functions in cryptohi.h. + | If you need to interoperate with a protocol that isn't implemented by NSS, then you may need to + use the ``PK11_`` functions. (This API pretty much consists of what was needed to implement SSL + and S/MIME, plus a few enhancements over the years to support JSS.) When using the ``PK11_`` + interfaces, the same principal applies: use the highest available function. + | If you are really trying to send a key, you should use ``PK11_PubWrapSymKey()``. For a low + level signature, use ``PK11_Sign()``. Both of these functions do the PKCS #1 wrapping of the + data. ``PK11_Sign`` does not do the BER encoding of the hash (as is done in ``SGN_`` + functions). + | If you are trying to just send data, use ``PK11_PubEncryptPKCS1``. + | ``PK11_PubEncryptRaw`` is the lowest level function. It takes a modulus size data and does a + raw RSA operation on the data. It's used to support SSL2, which modifies the key encoding to + include the SSL version number. + +.. _pkcs_1_v1.5_block_formatting: + +`PKCS #1 v1.5 Block Formatting <#pkcs_1_v1.5_block_formatting>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: + + | Question: + | In PKCS #1 v1.5 (Section 8.1 Encryption-block formatting) and v2.1 (Section 7.2.1 Encryption + operation), PKCS1 v1.5 padding is described like this: + | ``00 || 02 || PS || 00 || M`` + | but in PKCS #1 v2.0 (Section 9.1.2.1 Encoding operation, Step 3) and on the W3C web site + (http://www.w3.org/TR/xmlenc-core/#rsa-1_5), PKCS1 v1.5 padding is described like this: + | ``02 || PS || 00 || M`` + | 00 at the beginning is missing. Why? + | Answer: + | The version without the initial 00 says : + + .. container:: + + "PS is a string of strong pseudo-random octets [RANDOM] [...] long enough that the value of + the quantity being CRYPTed is one octet shorter than the RSA modulus" + + | + | The version with the initial 00 instead says to pad to the same length as the RSA modulus. + | "The same length as the RSA modulus with an initial octet of 0" and "one octet shorter without + that initial octet" are exactly the same thing because the formatted block is treated as a + big-endian big integer by the RSA algorithm. The leading 00 octet is simply eight most + significant 0 bits. For example, 0x00123456 is equal to 0x123456. + | Perhaps this change made in PKCS #1 v2.0 confused many people, so it was reversed in v2.1. + +.. _sample_code: + +`Sample Code <#sample_code>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: + + - :ref:`mozilla_projects_nss_nss_sample_code_nss_sample_code_sample4` + +`References <#references>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: + + - `RSA Labs PKCS #1 web site <http://www.rsasecurity.com/rsalabs/node.asp?id=2125>`__ + - `RFC 3447 <http://www.ietf.org/rfc/rfc3447.txt>`__: RSA PKCS #1 v2.1 + - `Poupou's Blog: Common question: How to encrypt using + RSA <http://www.dotnet247.com/247reference/a.aspx?u=http://pages.infinit.net/ctech/20031101-0151.html>`__
\ No newline at end of file diff --git a/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note8/index.rst b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note8/index.rst new file mode 100644 index 0000000000..efbb737d82 --- /dev/null +++ b/security/nss/doc/rst/legacy/nss_tech_notes/nss_tech_note8/index.rst @@ -0,0 +1,130 @@ +.. _mozilla_projects_nss_nss_tech_notes_nss_tech_note8: + +nss tech note8 +============== + +.. _background_information_on_libssl's_cache_functions_and_sids: + +`Background Information on libSSL's Cache Functions and SIDs <#background_information_on_libssl's_cache_functions_and_sids>`__ +------------------------------------------------------------------------------------------------------------------------------ + +.. container:: + +.. _nss_technical_note_8: + +`NSS Technical Note: 8 <#nss_technical_note_8>`__ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. container:: + + .. code:: + + 27 February 2006 + Nelson B. Bolyard + + Here is some background information on libSSL's cache functions and SIDs. + + A SID (or sslSessionID struct) contains all the info needed to restart + the ssl session at a later time on another socket. The protocol code + builds such a structure, and then asks the cache code (client or server) + to save the info. The protocol code can also ask to remove a SID from + the cache. + + Every SSL socket has two function pointers, ss->sec.cache and ss->sec.uncache, + which have the following types: + typedef void (*sslSessionIDCacheFunc) (sslSessionID *sid); + typedef void (*sslSessionIDUncacheFunc)(sslSessionID *sid); + + There are two separate implementations of each function, one for clients + and one for servers. The client implementation caches or uncaches the + SID in the client session cache. The server implementation caches or + uncaches the SID in the server session cache. + + For servers these pointers point to + sec->cache = ssl_sid_cache; + sec->uncache = ssl_sid_uncache; + which are functions defined in sslsnce.c, the server session cache source file. + + For clients these pointers point to + sec->cache = CacheSID; + sec->uncache = LockAndUncacheSID; + which are functions defined in sslnonce.c, the client session cache source file. + + The same cache/uncache API is used by both client and server code. + As originally designed, before calling the cache function, the caller was + responsible to fill in the session creation time (which might not be the + same as the time of insertion into the cache) and the session expiration + time, among other things. + + Since NSS 1.0, up until NSS 3.4, there were two global variables that + contained the expected session lifetimes for ssl2 and ssl3 sessions. + + extern PRUint32 ssl_sid_timeout; (the ssl2 session lifetime) + extern PRUint32 ssl3_sid_timeout; (the ssl3 session lifetime) + + Each of these variables applied to both client and server sessions. + That is, the client session lifetime was NOT separately settable from the + server session lifetime. + + These two variables were private, declared in a private header file. + There was no API function by which client programs could set these values. + However since NSS was delivered as archive libraries, client programs + merely declared these two variables for themselves, and then were able to + alter those variables directly. + + For server programs, the function for initializing the server session cache + would set these two variables according to two of the arguments to that + function. + + So, SSL protocol code that wanted to cache a SID would do these steps, + whether for client or for server: + + For ssl2: + sid->lastAccessTime = sid->creationTime = ssl_Time(); + sid->expirationTime = sid->creationTime + ssl_sid_timeout; + (*ss->sec.cache)(sid); + for ssl3: + sid->lastAccessTime = sid->creationTime = ssl_Time(); + sid->expirationTime = sid->creationTime + ssl3_sid_timeout; + (*ss->sec.cache)(sid); + + The cache API was defined such that the caller MUST set creationTime + properly, and may set expirationTime to the desired value or to zero. + If zero, then the called cache function would compute the correct + expiration time by adding the chosen timeout (from one of those two + global variables) to the SID's creationTime, giving the expirationTime. + + However, none of the callers relied on the ability of the respective + cache functions to be able to compute the expiration time. All callers + computed the expiration times explicitly, as shown above. + + The server side of the session cache code was largely rewritten for + NSS 3.4. The objectives were to make the server session cache faster, + and to fix bugs that caused corruption in multi-process servers, and also + to allow separate virtual servers to have their own session caches. + + The new approach was to use shared memory for the server session cache, + and to allow multiple different server session caches to coexist. + As part of that work, I decided that each cache would have its own + variables containing the SSL2 and SSL3 session durations. + This means that client cache session lifetimes are separate from server + session cache lifetimes, and that each server session cache may have its + own lifetimes. + + So, in NSS 3.4, the global variables ssl3_sid_timeout and ssl_sid_timeout + were intended to become the definitions for the client cache only, and + each server cache had its own new pair of variables for ssl2 and ssl3 + session lifetimes, i.e., cache->ssl2Timeout and cache->ssl3Timeout. + The server cache initialization function was intended to no longer alter + the variables ssl3_sid_timeout and ssl_sid_timeout, but rather to set the + server cache's variables. + + Since all the callers of the socket's cache function always initialized + both their creationTime and expirationTime using the client's session + lifetime variables, I changed the server's caching function to IGNORE the + expirationTime computed by the caller, and compute its own expiration + time, using the cache's own timeout values, or that was the intent. + + But an implementation flaw caused the caching code to continue to use the + client's timeout time values, not the server cache's own timeout values. + That is the subject of bug 223242.
\ No newline at end of file |