Last Comment Bug 152986 - RFE: Need a way to obtain the list of all email addresses in a cert.
: RFE: Need a way to obtain the list of all email addresses in a cert.
Status: RESOLVED FIXED
[cert]
:
Product: NSS
Classification: Components
Component: Libraries (show other bugs)
: unspecified
: All All
: P1 enhancement (vote)
: 3.7
Assigned To: Nelson Bolyard (seldom reads bugmail)
: Bishakha Banerjee
:
Mentors:
: 152984 (view as bug list)
Depends on:
Blocks: 50823 123417
  Show dependency treegraph
 
Reported: 2002-06-19 18:08 PDT by Stephane Saux
Modified: 2002-10-23 19:07 PDT (History)
10 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---


Attachments
One implementation, not most efficient, but should work. (6.86 KB, patch)
2002-10-22 23:50 PDT, Nelson Bolyard (seldom reads bugmail)
no flags Details | Diff | Splinter Review

Description Stephane Saux 2002-06-19 18:08:26 PDT
We currenlty can't adhere to the S/MIME standards that specify that a cert can
contain multiple email addresses because the only api in the s/mime libraries is:

char * NSS_CMSSignerInfo_GetSignerEmailAddress()


Note that NSS_CMSSignerInfo_GetSignerEmailAddress returns
CERTCertificate.emailAddr, which is created by a call to

lib/certdb/alg1485.c:CERT_GetCertificateEmailAddress(CERTCertificate *cert)

That function seems to be looking at all the right places, but only returns one
email address.

The very existence of CERTCErtificate.emailAddr is questionable, since certs can
have more than one.

Maybe we can add a field to CERTCertificate that would contain a list of email
addresses? Maybe we can have a function that computes the list on demand?

What do you think?
Comment 1 Stephane Saux 2002-06-20 11:42:01 PDT
The bug doesn't depend on 50823, it blocks it.
Comment 2 Alex Bishop 2002-06-24 22:32:39 PDT
*** Bug 124070 has been marked as a duplicate of this bug. ***
Comment 3 Wan-Teh Chang 2002-06-25 15:21:50 PDT
*** Bug 152984 has been marked as a duplicate of this bug. ***
Comment 4 Wan-Teh Chang 2002-07-22 14:58:08 PDT
It seems that CERTCErtificate.emailAddr is used as the
key to the S/MIME profiles.  CERT_GetCertificateEmailAddress
recomputes the email address every time; it does not use
CERTCErtificate.emailAddr.

So I think we also need to look at how the S/MIME profiles
are stored to handle the possibility that multiple email
addresses correspond to the same S/MIME profile.
Comment 5 Robert Relyea 2002-09-06 11:04:07 PDT
Unfortunately the CERTCertificate datastructure is pretty much locked in place
as long as we are still mantaining binary compatibility (Unfortunately the data
structure was exported when it should have been Opaque).

The underlying NSS database does not handle multiple email address all that
well, since there is a one-for-one index between email address and certificate
Subject. We can, however provide a function which lists all the valid email
addresses for a given certificate. I don't think will give you all you need to
handle the many-to-many email-to-certificate semantic we want to support.

Adding this function is still scheduled for NSS 3.6, P2.
Comment 6 Wan-Teh Chang 2002-09-06 17:25:42 PDT
Assigned the bug to Nelson.
Comment 7 Wan-Teh Chang 2002-09-25 15:36:41 PDT
Nelson, please investigate how much work it is to
implement a function that takes a cert and an email
address as arguments and returns a Boolean indicating
whether the cert contains that email address.

This Boolean function should meet the immediate need
of the S/MIME code in the Mozilla client.  It is not as
general as the function Stephane requested, but avoids the
whole issues of the format of the list of email addresses,
whether the list should be returned or stored in
CERTCertificate, and how to free the list.
Comment 8 Wan-Teh Chang 2002-10-01 11:57:03 PDT
Moved to NSS 3.7, priority P1.
Comment 9 Nelson Bolyard (seldom reads bugmail) 2002-10-17 23:05:07 PDT
PSM folks,

NSS_CMSSignerInfo_GetSignerEmailAddress takes this argument:
         NSSCMSSignerInfo *sinfo

Another function in that family, NSS_CMSSignerInfo_GetSigningCertificate
also takes a NSSCMSSignerInfo *, and returns a CERTCertificate *.
The CERTCertificate pointer returned by NSS_CMSSignerInfo_GetSigningCertificate 
is a new reference to the CERTCertificate, and the reference must be destroyed 
with a call to CERT_DestroyCertificate to avoid a leak.  

I propose two new functions:
char * CERT_GetFirstEmailAddress(CERTCertificate * cert);
and
char * CERT_GetNextEmailAddress(char * prevEmailAddress);

These functions will return a pointer to a UTF8 string, or NULL.  
The value returned by GetFirst will be passed to GetNext, and each value
returned by GetNext will be passed to the next call to GetNext, until 
GetNext returns a NULL.

The char * pointers returned point to storage that is part of the 
CERTCertificate's arena.  The pointer will remain good as long as the caller
retains a reference to the CERTCertificate.  The caller must strdup (or
otherwise copy) the data if he wishes to keep it after releasing the 
reference to the CERTCertificate.   

How does this sound?  
I'm coding it up now.
Comment 10 Nelson Bolyard (seldom reads bugmail) 2002-10-17 23:12:19 PDT
One minor correction to the proposal:
instead of taking and returning char *, they'll take and return const char *.
That should keep the callers from doing bad things with the data.
Comment 11 Wan-Teh Chang 2002-10-18 08:10:43 PDT
Nelson,

Ideally we just need one function:

const char *const* CERT_GetEmailAddresses(CERTCertificate *cert);

or

char ** CERT_GetEmailAddresses(CERTCertificate *cert, PLArenaPool *arena);

I know why you proposed the CERT_GetFirstEmailAddress and
CERT_GetNextEmailAddress functions -- you want to store the
list of email addresses in CERTCertificate without adding a
new field.  They are fine by me although they look
inefficient (we need a strlen call rather than a pointer
increment to get the next email address) to someone who
doesn't know the reason behind them.
Comment 12 Wan-Teh Chang 2002-10-18 08:15:28 PDT
Can email addresses be UTF8 strings?
Comment 13 Stephane Saux 2002-10-18 19:53:25 PDT
taka, do you know what kind of encoding there can be in an email address?
Comment 14 Nelson Bolyard (seldom reads bugmail) 2002-10-18 20:30:36 PDT
Let's not get hung up on UTF8.  
The scheme I propose will work on any character set that does not use wide 
characters, and that has no zero bytes in any of the characters that might
be used in an email address.  That includes the following character sets,
and probably others, too:

UTF8, ISO-Latin-1 and its subsets, such as ASCII & IA5 would all work with this 
scheme. 
Comment 15 Takayuki Tei 2002-10-19 10:26:09 PDT
Are you expecting addr-spec (e.g. taka@netscape.com) only?
Or, name-addr (e.g. Takayuki Tei <taka@netscape.com>) ?
Comment 16 Wan-Teh Chang 2002-10-21 10:17:59 PDT
I was just wondering whether we need to specify the
character encoding of the strings returned by the
new functions Nelson proposed in comment #9.
Comment 17 Nelson Bolyard (seldom reads bugmail) 2002-10-22 13:42:44 PDT
In reply to comment 15,  Taka, I expect that all the email addresses in
the certificate will be addr-spec only.  RFC 3280 says:

   When the subjectAltName extension contains an Internet mail address,
   the address MUST be included as an rfc822Name.  The format of an
   rfc822Name is an "addr-spec" as defined in RFC 822 [RFC 822].  An
   addr-spec has the form "local-part@domain".  Note that an addr-spec
   has no phrase (such as a common name) before it, has no comment (text
   surrounded in parentheses) after it, and is not surrounded by "<" and
   ">".  Note that while upper and lower case letters are allowed in an
   RFC 822 addr-spec, no significance is attached to the case.

It also says:

   In addition, legacy implementations exist where an RFC 822 name is
   embedded in the subject distinguished name as an EmailAddress
   attribute.  The attribute value for EmailAddress is of type IA5String
   to permit inclusion of the character '@', which is not part of the
   PrintableString character set.  EmailAddress attribute values are not
   case sensitive (e.g., "fanfeedback@redsox.com" is the same as
   "FANFEEDBACK@REDSOX.COM").

IA5String is a subset of ASCII.

In reply to comment 16,  Wan-Teh, RFC 822 and its successor RFC 2822 both state 
that all the characters in the email headers (including email addresses) must be 
ACII characters in the range 1-127.  I expect we will see some certificates
with ISO-Latin-1 characters in the email addresses, but these are similar 
enough to ASCII for the purposes of string comparison, and for this API. 

BTW, to permit alternative implementations in the future, I now propose that
the two functions be:

const char * 
CERT_GetFirstEmailAddress(CERTCertificate *cert);
const char * 
CERT_GetNextEmailAddress(CERTCertificate *cert, const char *prevEmailAddress);

This permits the internal opaque implementation to use either a environment-like 
super-string, or an array of pointers to strings, without requiring any 
change to the callers.

I'm waiting for feedback from Stephane's team on this proposal.
Comment 18 Takayuki Tei 2002-10-22 13:57:46 PDT
I recommend the API to do validation so that e-mail addresses are 
guranteed to have ASCII characters only.  You shouldn't allow
any characters including Latin-1, otherwise it will break things
down the road.
Comment 19 Nelson Bolyard (seldom reads bugmail) 2002-10-22 23:50:38 PDT
Created attachment 103833 [details] [diff] [review]
One implementation, not most efficient, but should work.

If performance is a problem with this implementation, the API allows us to
change it without making client's change.
Comment 20 Nelson Bolyard (seldom reads bugmail) 2002-10-23 13:35:35 PDT
Hey gang:

Do we have any certs with multiple email addresses in them for testing 
this new code?  Is so, please email them to me. Thanks.
Comment 21 Julien Pierre 2002-10-23 13:51:50 PDT
Nelson,

I'm going to create a Thawte one with both my home and work email address, and
will email you.
Comment 22 Nelson Bolyard (seldom reads bugmail) 2002-10-23 14:02:26 PDT
I found a cert with 2 email addresses in it.  They were the same address.
The address is returned twice, once by GetFirst and again by GetNext.

Patch checked in.
Comment 23 Charles Rosendahl 2002-10-23 15:12:32 PDT
So this is 3.7, correct?  Won't make it into Buffy then?
Comment 24 Nelson Bolyard (seldom reads bugmail) 2002-10-23 15:21:41 PDT
What NSS release will Buffy use?
I've not received any request to do this in any other release than 3.7.

This change adds new API functions to NSS, by which an application could
access this info.  We generally don't add new API functions to NSS in 
patch releases (such as 3.6.1).  

But even if we did add it to 3.6.1, would any new code be written in PSM 
to make use of this new feature for Buffy?

Comment 25 Wan-Teh Chang 2002-10-23 15:42:57 PDT
Charles,

We plan to release NSS 3.7 RTM on 3/3/2003 and the
earliest time Mozilla can have to the new NSS 3.7
APIs is the NSS 3.7 Beta release on 2/10/2003.
Kai can pull NSS 3.7 pre-release for his development.

If this is too late for you we can talk about it.
Our schedule is tentative at the moment and there
is some flexibility to adjust it.
Comment 26 Nelson Bolyard (seldom reads bugmail) 2002-10-23 18:34:46 PDT
There's another issue about this API that needs to be resolved, perhaps
resulting in a change to the code just checked in.

The old CERTCertificate->emailAddr string was downshifted.  Every character
in it came from a call to tolower().  Each byte of the original email
address in the cert was passed to tolower, and the result was stored in 
the emailAddr string.  

So, when I implemented the new functions, I duplicated this behavior.  
Perhaps this is not the desired behavior.  

If the strings returned by the new API functions are intended for display
purposes, then they should not be downshifted.  OTOH, if they are only
intended for comparison purposes, then perhaps downshifting is OK,
although only characters less than 0x80 should be downshifted, IMO.

Stephane, please help me get resolution to this ASAP.
Comment 27 Stephane Saux 2002-10-23 19:07:13 PDT
Downshifting is the right thing to do.
These email addresses may end up being displayed in the cert manager, where all
email addresses for the "other people certs" tab are downshifted.

Note You need to log in before you can comment on or make changes to this bug.