Closed
Bug 78959
Opened 23 years ago
Closed 23 years ago
New NSS function returns SSL info not presently available
Categories
(NSS :: Libraries, enhancement, P1)
Tracking
(Not tracked)
RESOLVED
FIXED
3.4
People
(Reporter: nelson, Assigned: nelson)
References
Details
Attachments
(1 file)
4.44 KB,
text/plain
|
Details |
Bug http://bugzilla.mozilla.org/show_bug.cgi?id=78837 requires that NSS provide a way to access certain pieces of information about an existing SSL connection so that PSM can display them. The function presently available for this purpose, SSL_SecurityStatus() is documented at http://www.mozilla.org/projects/security/pki/nss/ref/ssl/sslfnc.html#1092805 This function is inadequate in several respects, which I'll enumerate below. Below that, I propose a new function to supersede SSL_SecurityStatus. I want to solicit your input on whether this new function adequately meets the needs. This work is not yet part of any NSS PRD, and not scheduled for anyh Inadequacies of SSL_SecurityStatus: 1. Does not indicate key exchange algorithm. RSA? DHE? Fortezza-KEA? 2. Does not indicate strength of key exchange key/value 512 bits? 1024 bits? other? 3. Does not indicate server authentication algorithm. RSA? DSA? 4. Does not indicate server authentication key size. 512 bits? 1024 bits? other? 5. Does not indicate SSL protocol version used. SSL 2? SSL 3.0? TLS (SSL 3.1)? 6. Does not indicate the digest algorithm used for message authentication (MAC). SHA1? MD5? 6.1 Does not indicate the size of the digest used for MACs. Presently, this value is implicitly determined from the particular MAC algorithm, but in the future there will be "truncated MACs" which are shorter than the full size given by the algorithm. 7. Returns a malloced ASCII string to identify the symmetric cipher used. - These strings are not localized (although it's not clear how to localize TLAs like RC2 and DES). - The strings are inconsistent in identification of export status (key strength). For example, RC2-CBC with a 40 bit export key is identified as RC2-CBC-Export for SSL2 and as RC2-CBC-40 for SSL3. - Since the size of the key is available as an integer, there's really no need to identify RC4 with a 40-bit key as a separate cipher from RC4 with a 128-bit key. 8. Provides no information about whether client key exchange was done, and what cert was used, or what key size or client authentication algorithm was used. 9. Returns two values named "keySize" and "secretKeySize" whose meanings are unclear to and often misinterpreted by programmers and users. 10. Returns RFC 1485 (ASCII-encoded) issuer and subject names for the peer's certificate (if any), but no other decoded info about the cert is made available. However, the application can obtain the peer's cert and extract what it needs with other libcert functions. 11. Returns an indicator of the "level" of security: Off, low, high, which is based on outdated levels of expectation. (56-bits is no longer considered high security, for example.) The application ought to make this value judgement for itself, IMO. Before you read the proposed new function, please familiarize yourself with the documentation on the existing function, at http://www.mozilla.org/projects/security/pki/nss/ref/ssl/sslfnc.html#1092805 Proposed new function and structure. The newly proposed function returns all info in a caller-supplied structure. The caller does not have to free any memory allocated by the function. No strings are returned. All values are numeric. Translating the returned numbers into strings is the responsibility of the calling application. typedef enum { ssl_calg_null = 0, ssl_calg_rc4 = 1, ssl_calg_rc2 = 2, ssl_calg_des = 3, cssl_alg_3des = 4, ssl_calg_idea = 5, ssl_calg_fortezza = 6, /* skipjack */ ssl_calg_aes = 7 /* coming soon */ } SSL3CipherAlgorithm; typedef struct SSLChannelInfoStr { PRUint32 length; PRUint16 protocolVersion; PRUint16 cipherSuite; SSL3SignType authAlgorithm; PRUint32 authKeyBits; SSLKEAType keaType; PRUint32 keaKeyBits; SSL3CipherAlgorithm bulkCipher; PRUint16 symKeyBits; PRUint16 symKeySpace; PRUint16 effectiveKeyBits; SSL3MACAlgorithm macAlgorithm; PRUint16 macBits; PRUint8 reserved[64]; } SSLChannelInfo; extern SECStatus SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info); (I know that struct is not optimally packed, but at this point, I want to discuss whether the requisite info is there, not how the struct looks or struct member names. ) Notes: - The structure has space reserved for future expansion. Future versions of the structure will replace some of the reserved elements, but the overall length will remain unchanged. The length field at the beginning indicates how much of the structure has been filled in by the present version of NSS (not counting the unused reserved portion). - All of these types (except SSL3CipherAlgorithm shown above) are presently defined in ssl header files, but some are defined in private header files, and will have to be moved to public header files. - protocolVersion is the SSL protocol version. Zero means SSL was not used. See SSL_LIBRARY_VERSION macros in sslproto.h for defined versions. - cipherSuite values are defined in sslproto.h. For SSL2, these are the SSL_EN_ symbols. - symKeyBits is the number of bits in the derived key for the symmetric bulk encryption cipher. - symKeySpace is the logarithm (base 2) of the number of unique keys that can be derived for the symmetric cipher given the known values for the client and server "random" variables, and (for SSL2 only) the known bits for the master secret. This number is not greater than symKeyBits. - effectiveKeyBits is the logarithm (base 2) of the number of keys that must be tried (worst case) to find the symmetric cipher key, given the best available cryptanalysis of the cipher. This number is not greater than symKeySpace. - macBits is the number of bits in the MAC in each SSL record, which may be less than or equal to the maximum number provided by the MAC algorithm. - This struct does not contain any info about the peer's cert. There is already a function for obtaining a reference to the peer's CERTCertificate struct, and there are accessor functions that extract values (e.g. portions of the name, validity dates, etc.) from that struct. For example, CERT_NameToASCII can be used to to extract the issuer name or subject name from the certificate reference. - This struct does not contain any info about the local cert (if any) that was used to do client authentication. However, since the application provides that cert to the SSL library through a callback function, the application ought to already have a pointer to that cert. A function to return a reference to the local client cert could be added if needed. An alternative proposal uses short arrays of char rather than integer values for the names of the algorithms. This proposal asserts that the names of the algorithms (e.g. "RSA", "DSA", "DES", "MD5", etc.) do not need localization. typedef struct SSLChannelInfoStr { PRUint32 length; PRUint16 protocolVersion; PRUint16 cipherSuite; PRUint32 authKeyBits; PRUint32 keaKeyBits; PRUint16 symKeyBits; PRUint16 symKeySpace; PRUint16 effectiveKeyBits; PRUint16 macBits; char authAlgorithm[32]; char keaType [32]; char bulkCipher [32]; char macAlgorithm [32]; PRUint8 reserved [64]; } SSLChannelInfo; Comments on these proposals are invited.
Assignee | ||
Comment 1•23 years ago
|
||
I'm markign this assigned, but note that the target release for this new feature has not yet been determined.
Blocks: 78837
Status: NEW → ASSIGNED
Comment 2•23 years ago
|
||
In addition to the inadequacies mentioned in the initial statement of this bug, the current API does not provide information about the FIPS status of the connection. The FIPS status needs to relect whether the TLS form of key derivation was used together with a combination of FIPS approved encryption and mac algorithms.
Assignee | ||
Comment 5•23 years ago
|
||
Assignee | ||
Comment 6•23 years ago
|
||
This is checked in on the trunk. The test clients and server programs now use the new function instead of the old, and report the information about the SSL connection. It should be easy to modify the QA test scripts to verify that the reported information matches the expected information. It may be necessary or desirable to modify the test clients/server to display this info on stdout instead of stderr, or vice versa.
Status: ASSIGNED → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
Comment 7•23 years ago
|
||
Here are my comments on the SSLChannelInfo structure in
attachment 49707 [details].
1. The bitfield for isFIPS and reservedBits needs to be
declared PRUint32 to ensure it has at least 32 bits.
2. I withdraw my suggestion for the flexibility to allow
future expansion of the structure. You can consider
removing the length and reserved fields.
3. For each algorithm, why do you return both a string
and an enum (for example, symCipherName and symCipher)?
Other than these, the structure looks good.
Comment 8•23 years ago
|
||
Jamie, please review the SSLChannelInfo structure and see if it has all the information required by JSSE.
Comment 9•23 years ago
|
||
Here are three things that JSSE (the Java SSL API) provides that may be difficult to implement with the existing NSS SSL API, and with the proposed SSL_GetChannelInfo. 1. Cipher suite and protocol strings SSLSession.getCipherSuite() returns the cipher suite as a string, apparently using the names out of the specs. Examples are "SSL_RSA_WITH_RC4_128_MD5" and "SSL_DH_anon_WITH_DES_CBC_SHA". It also wants a string describing the protocol. For example, "SSLv3". I can create a more exhaustive list of these strings if someone can tell me where I can connect to SSLv2 and TLS servers. 2. Session Data - Creation Time: "the time at which this Session representation was created" - Last Accessed Time: ***BEGIN JAVADOC**** Returns the last time this Session representation was accessed by the session level infrastructure, in milliseconds since midnight, January 1, 1970 UTC. Access indicates a new connection being established using session data. Application level operations, such as getting or setting a value associated with the session, are not reflected in this access time. This information is particularly useful in session management policies. For example, a session manager thread could leave all sessions in a given context which haven't been used in a long time; or, the sessions might be sorted according to age to optimize some task. ****END JAVADOC**** - ID: "the identifier assigned to this session". It is an array of 32 bytes. 3. Certificates - local certificates: the certificate(s) that were sent to the peer during handshaking. Returns an ordered array of certificates, with the local certificate first followed by any certificate authorities. This method allows the caller to know which certificate chain was actually used. - peer certificates: an ordered array of peer X.509 certificates, with the peer's own certificate first followed by any certificate authorities.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Comment 10•23 years ago
|
||
FYI, the javadoc for this stuff is at http://java.sun.com/j2se/1.4/docs/api/javax/net/ssl/package-summary.html SSLSession and SSLSocket are relevant.
Comment 11•23 years ago
|
||
Jamie, thanks for reviewing the SSL_GetChannelInfo() API and noting the additional requirements from JSSE. Nelson, I'd like to hear your opinion on Jamie's comments. My own comments below. 1. Cipher suite and protocol strings It seems that the ciphersuite string that JSSE needs can be constructed from the algorithm name strings returned by SSL_GetChannelInfo(). 2. Session Data - Creation Time - Last Accessed Time - ID If these session data should be returned by SSL_GetChannelInfo() but you don't have time to implement them, make sure that we have enough space for them in the 'reserved' array at the end of the SSLChannelInfo structure. (In fact, we could just add three new fields marked as reserved for these session data.) We can implement them in a future NSS release. 3. Certificates - local certificates - peer certificates It seems to me that these can be returned by a separate function. If you think they should be returned by SSL_GetChannelInfo(), make sure that we have enough space for them in the 'reserved' array.
Assignee | ||
Updated•23 years ago
|
Status: REOPENED → ASSIGNED
Assignee | ||
Comment 12•23 years ago
|
||
Please evaluate the following alterative proposal for the implementation of SSL_GetChannelInfo(). This proposal recognizes that most of the info about the session is completely encoded in the cipher suite number, and there is very little information about the SSL session that is not specified uniquely by the cipher suite number. It also permits the application to inquire about the characteristics of a ciphersuite even when no SSL session is in progress. This proposal creates another new function: SSL_GetCipherSuiteInfo() which takes a ciphersuite number and returns all the info about it. I desire your feedback on this proposal. typedef struct SSLChannelInfoStr { PRUint32 length; PRUint16 protocolVersion; PRUint16 cipherSuite; /* server authentication info */ PRUint32 authKeyBits; /* key exchange algorithm info */ PRUint32 keaKeyBits; /* session info */ PRUint32 creationTime; /* seconds since Jan 1, 1970 */ PRUint32 lastAccessTime; /* seconds since Jan 1, 1970 */ PRUint32 expirationTime; /* seconds since Jan 1, 1970 */ PRUint32 sessionIDLength; /* up to 32 */ PRUint8 sessionID [32]; PRUint8 reserved [64]; } SSLChannelInfo; SECStatus SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len); typedef struct SSLCipherSuiteInfoStr { PRUint16 length; PRUint16 cipherSuite; /* Cipher Suite Name */ const char * cipherSuiteName; /* server authentication info */ const char * authAlgorithmName; SSLSignType authAlgorithm; /* key exchange algorithm info */ const char * keaTypeName; SSLKEAType keaType; /* symmetric encryption info */ const char * symCipherName; SSLCipherAlgorithm symCipher; PRUint16 symKeyBits; PRUint16 symKeySpace; PRUint16 effectiveKeyBits; /* MAC info */ const char * macAlgorithmName; SSLMACAlgorithm macAlgorithm; PRUint16 macBits; PRUintn isFIPS : 1; PRUintn reservedBits :31; PRUint8 reserved [64]; } SSLCipherSuiteInfo; SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite, SSLCipherSuiteInfo *info, PRUintn len); This last function can be used together with the list of implemented SSL ciphersuites provided by libSSL (*) for the application to display or choose from a list of ciphersuites that always matches the current libSSL. (*) see http://lxr.mozilla.org/mozilla/source/security/nss/lib/ssl/ssl.h#58 I would also propose to reorder the list of implemented SSL ciphersuites to be in descending order of desirability (strength).
Comment 13•23 years ago
|
||
This latest proposal provides all the info needed by SSLSession, except the certificates. Will those be provided by some other function?
Assignee | ||
Comment 14•23 years ago
|
||
The API already contains functions to get the peer's cert, and to get the chain for that (or any) cert. I'm planning to change libssl so that it will hold onto the peer cert and its chain for the duration of the SSL connection rather than only for the duration of processing the peer's certificate message (as it does today). This change can be done in a way that is fully backwards compatible. There is no function to get the "local" cert. I'm thinking about that issue. The local application always tells libSSL which cert to send (for client auth), or the set of certs from which libssl should choose one appropriate for the negotiated ciphersuite (for server auth), so one might argue that the application should already possess the "local" cert without asking libssl. But if libSSL can be made to easily answer this question, then perhaps it should. Stay tuned.
Updated•23 years ago
|
Priority: P2 → P1
Assignee | ||
Comment 15•23 years ago
|
||
I have just added the following new function to libSSL. I'm going to assume that this meets the requirement unless someone tells me otherwise. /* ** Return a new reference to the certificate that was most recently sent ** to the peer on this SSL/TLS connection, or NULL if none has been sent. */ SSL_IMPORT CERTCertificate * SSL_LocalCertificate(PRFileDesc *fd); Finally, note that the final version of the structures SSLChannelInfoStr and SSLCipherSuiteInfoStr did not have the "reserved" byte arrays that were proposed above. I'm marking this bug fixed. Please reopen it if you think it is not.
Status: ASSIGNED → RESOLVED
Closed: 23 years ago → 23 years ago
Resolution: --- → FIXED
Assignee | ||
Comment 16•23 years ago
|
||
Jamie told me that SSL_LocalCertificate must return the last cert previously sent on this SSL session, even if it was on a different (e.g. earlier) connection. So, I am reopening this, and must reimplement SSL_LocalCertificate.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Assignee | ||
Comment 17•23 years ago
|
||
I added a local Certificate value to the client session cache to make SSL_LocalCertificate remember the client auth cert that we sent when the SSL session was established accross later restarts of the session. A similar effect on the server side was achieved without adding more cert storage in the server cache. The strsclnt and selfserv programs may now be used to test the SSL_LocalCertificate function, as well as the other new functions created for this enhancement request.
Status: REOPENED → RESOLVED
Closed: 23 years ago → 23 years ago
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•