Re: How to get a list of SubjectAltNames of a cert in NSS

2017-03-03 Thread Paul Wouters

On Fri, 3 Mar 2017, Robert Relyea wrote:


Yes, NSS only looks at the first subjectAltName section. That section can and 
should hold all the alt names (That's certainly the case with SSL
certificates).


Ok, so maybe we have generated certificates in a bad way :)

See the attached python script that generates these :)


  So there are 3 subjectAltName sections.

Hmm Are you sure these aren't being colapsed into a single subjectAltName 
section with multiple subjectAltNames in it?


Yes because I was testing the IP: and DNS: and email= SAN's and my code
showed it only looped over the first one.


CERT_VerifyCertName() verifies against either the SAN or the CN (SSL 
processing). it supports multiple subjectAltNames, but they all are expected to
be in the same section.


So it seems that this function would do everything I need. I'll see
about changing my certificates to have one SAN section and then
confirm if it can pick up the DNS name or email address from CN
and SAN.

Thanks,

Paul#!/usr/bin/python
""" dist_certs.py: create a suite of x509 certificates for the Libreswan
test harness

 Copyright (C) 2014-2015 Matt Rogers 
 Copyright (C) 2015 Andrew Cagney 

 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
 Free Software Foundation; either version 2 of the License, or (at your
 option) any later version.  See .

 This program is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.

WARNING! Your PyOpenSSL needs a patch from here:
https://github.com/pyca/pyopenssl/pull/161
NSS doesn't allow md5 CRL signatures. This patch lets you use
the CRL export method and specify an acceptable signature type.

 """

import os
import sys
import ssl
import shutil
import subprocess
import time
from datetime import datetime, timedelta
import pexpect
from OpenSSL import crypto

CRL_URI = 'URI:http://nic.testing.libreswan.org/revoked.crl'

dates = {}
ca_certs = {}
end_certs = {}
endrev_name = ""
top_caname=""

def reset_files():
for dir in ['keys/', 'cacerts/', 'certs/', 'pkcs12/',
'pkcs12/curveca', 'pkcs12/mainca',
'pkcs12/otherca', 'pkcs12/badca', 'crls/']:
if os.path.isdir(dir):
shutil.rmtree(dir)
os.mkdir(dir)
for file in ['nss-pw']:
if os.path.isfile(file):
os.remove(file)

def writeout_cert(filename, item,
  type=crypto.FILETYPE_PEM):
with open(filename, "w") as f:
f.write(crypto.dump_certificate(type, item))


def writeout_privkey(filename, item,
 type=crypto.FILETYPE_PEM):
with open(filename, "w") as f:
f.write(crypto.dump_privatekey(type, item))


def create_keypair(algo=crypto.TYPE_RSA, bits=1024):
""" Create an OpenSSL keypair
"""
pkey = crypto.PKey()
pkey.generate_key(algo, bits)
return pkey


def create_csr(pkey, CN,
   C=None, ST=None, L=None, O=None, OU=None,
   emailAddress=None, algo='sha1'):
""" Create the certreq
"""
req = crypto.X509Req()
subject = req.get_subject()
subject.CN = CN
subject.C = C
subject.ST = ST
subject.L = L
subject.O = O
subject.OU = OU
subject.CN = CN
subject.emailAddress = emailAddress
req.set_pubkey(pkey)
req.sign(pkey, algo)
return req

def add_ext(cert, kind, crit, string):
cert.add_extensions([crypto.X509Extension(kind, crit, string)])

def set_cert_extensions(cert, issuer, isCA=False, isRoot=False, ocsp=False, 
ocspuri=True):
ku_str = 'digitalSignature'
eku_str = ''
ocspeku = 'serverAuth,clientAuth,codeSigning,OCSPSigning'
cnstr = str(cert.get_subject().commonName)

if isCA:
ku_str = ku_str + ',keyCertSign,cRLSign'
if "badca" in str(issuer.get_subject().commonName):
bc = "CA:FALSE"
else:
bc = "CA:TRUE"
else:
bc = "CA:FALSE"

add_ext(cert, 'basicConstraints', False, bc)

if not isCA:
dnsname = "DNS: " + cnstr
if cnstr == "east.testing.libreswan.org":
dnsname = "%s,%s"%(dnsname , "DNS:east.alias")
add_ext(cert, 'subjectAltName', False, "IP: 192.1.2.23")
add_ext(cert, 'subjectAltName', False, dnsname)

Re: How to get a list of SubjectAltNames of a cert in NSS

2017-03-03 Thread Robert Relyea

On 03/03/2017 02:48 PM, Robert Relyea wrote:

On 03/03/2017 09:42 AM, Paul Wouters wrote:

On Fri, 3 Mar 2017, Robert Relyea wrote:


 [offlist]


redirected back to the list, since the item I was concerned about is not
a concern.


 Thanks for the info. I looked at it and have two questions and one
 concern (which is why this is offlist)
I'm not sure what list this was from. I don't remember seeing the 
thread.


dev-tech-crypto@lists.mozilla.org


 - Why not export this NSS function for everyone?


Which function?


Sorry, I was referring to:

cert_VerifySubjectAltName(const CERTCertificate *cert, const char 
*name);


Certainly as named, we would export it, but we could wrap the function 
as CERT_VerifySubjectAltName()
and export that function. 


Arg... typing to fast drops negations. this should read

"Certainly as names we would NOT export it, but we could wrap the 
function as CERT_VerifySubjectAltName() and export that function()."


Lower case function names is an indicator the the function is local, at 
least to the NSS directory, if not to the .c file itself. Anything 
exported even within the NSS shared library (yet alone to the 
application) sould have an all cap prefix.


bob

--
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto


Re: How to get a list of SubjectAltNames of a cert in NSS

2017-03-03 Thread Robert Relyea

On 03/03/2017 09:42 AM, Paul Wouters wrote:

On Fri, 3 Mar 2017, Robert Relyea wrote:


 [offlist]


redirected back to the list, since the item I was concerned about is not
a concern.


 Thanks for the info. I looked at it and have two questions and one
 concern (which is why this is offlist)
I'm not sure what list this was from. I don't remember seeing the 
thread.


dev-tech-crypto@lists.mozilla.org


 - Why not export this NSS function for everyone?


Which function?


Sorry, I was referring to:

cert_VerifySubjectAltName(const CERTCertificate *cert, const char 
*name);


Certainly as named, we would export it, but we could wrap the function 
as CERT_VerifySubjectAltName()

and export that function.




Basically in IKE you can set an ID different from a DN. So if someone
sets ID_FQDN (eg vpn.example.com) then we want to lookup and ensure that
the certificate is really matching that ID. IKE also allows specifying
email addresses and IP's. So we need to look for:

- email= in the DN
- subjectAltName of type DNSname
- subjectAltName of type IP
- subjectAltName of type email address.

It looks that CERT_GetFirstEmailAddress() and CERT_GetNextEmailAddress()
gets me the email= from the DN and all email address in the first
subjectAltName section, but not in subsequent subjectAltName sections.


Yes, NSS only looks at the first subjectAltName section. That section 
can and should hold all the alt names (That's certainly the case with 
SSL certificates).


I think you may be confused with the openSSL API. When openSSL says:

Please make sure the following details are correct before proceeding any 
further.

CommonName: server1.example.com
subjectAltName: DNS:server1.example.com
subjectAltName: DNS:mail.example.com
subjectAltName: DNS:www.example.com
subjectAltName: DNS:www.sub.example.com
subjectAltName: DNS:mx.example.com
subjectAltName: DNS:support.example.com
No additional information will be included on certificates because it can not 
be automatically checked by the system.

It will create a single subjectAltName with all those names in it:

X509v3 Subject Alternative Name:
DNS:server1.example.com, othername:, DNS:mail.example.com, 
othername:, DNS:www.example.com, othername:, DNS
:www.sub.example.com, othername:, DNS:mx.example.com, othername:, DNS:support.example.com, othername:

Are you sure the certificate you have actually has multiple 
subjectAltName sections?




The same is true for cert_VerifySubjectAltName() which seems to only
look at the first subjectAltName section as well.

The certificates I use for testing use this openssl/python code:

-   add_ext(cert, 'subjectAltName', False, dnsname)
+   if cnstr == "east.testing.libreswan.org":
+   dnsname = "%s,%s"%(dnsname , "DNS:east.alias")
+   add_ext(cert, 'subjectAltName', False, "IP: 
192.1.2.23")

+   add_ext(cert, 'subjectAltName', False, dnsname)
+   add_ext(cert, 'subjectAltName', False, "email: 
user1@%s"%cnstr)


So there are 3 subjectAltName sections.


Hmm Are you sure these aren't being colapsed into a single 
subjectAltName section with multiple subjectAltNames in it?


In general NSS tends to be stingy by default on the functions it 
exports,


I completely understand that :)

I believe Kai has already exported several functions upstream for you 
that will go into RHEL 7.


Yes, and we've already updated libreswan to make use of this in upstream
and fedora rawhide! Thanks!


 The code I see in NSS seems to assume there is only one SAN section? I
 checked and it does not create one big list of all the SAN extensions,
 because I don't see my IP address SAN in the above example.


It doesn't. For most of NSS we usually are looking for a specific SAN 
(like a particular DNS name, or an email address.), so it loops 
through them all.


I'm surprised the SAN processing isn't exported since applications 
that override the SSL name check would need it.


You do export CERT_VerifyCertName() which uses this function. So maybe I
was trying to use the wrong function. But it seems this function also
does not process multiple subjectAltName sections.


CERT_VerifyCertName() verifies against either the SAN or the CN (SSL 
processing). it supports multiple subjectAltNames, but they all are 
expected to be in the same section.


bob


--
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto


Re: How to get a list of SubjectAltNames of a cert in NSS

2017-03-03 Thread Paul Wouters

On Fri, 3 Mar 2017, Robert Relyea wrote:


 [offlist]


redirected back to the list, since the item I was concerned about is not
a concern.


 Thanks for the info. I looked at it and have two questions and one
 concern (which is why this is offlist)

I'm not sure what list this was from. I don't remember seeing the thread.


dev-tech-crypto@lists.mozilla.org


 - Why not export this NSS function for everyone?


Which function?


Sorry, I was referring to:

cert_VerifySubjectAltName(const CERTCertificate *cert, const char 
*name);

Basically in IKE you can set an ID different from a DN. So if someone
sets ID_FQDN (eg vpn.example.com) then we want to lookup and ensure that
the certificate is really matching that ID. IKE also allows specifying
email addresses and IP's. So we need to look for:

- email= in the DN
- subjectAltName of type DNSname
- subjectAltName of type IP
- subjectAltName of type email address.

It looks that CERT_GetFirstEmailAddress() and CERT_GetNextEmailAddress()
gets me the email= from the DN and all email address in the first
subjectAltName section, but not in subsequent subjectAltName sections.

The same is true for cert_VerifySubjectAltName() which seems to only
look at the first subjectAltName section as well.

The certificates I use for testing use this openssl/python code:

-   add_ext(cert, 'subjectAltName', False, dnsname)
+   if cnstr == "east.testing.libreswan.org":
+   dnsname = "%s,%s"%(dnsname , "DNS:east.alias")
+   add_ext(cert, 'subjectAltName', False, "IP: 192.1.2.23")
+   add_ext(cert, 'subjectAltName', False, dnsname)
+   add_ext(cert, 'subjectAltName', False, "email: 
user1@%s"%cnstr)

So there are 3 subjectAltName sections.


In general NSS tends to be stingy by default on the functions it exports,


I completely understand that :)

I believe Kai has already exported several functions upstream for you that 
will go into RHEL 7.


Yes, and we've already updated libreswan to make use of this in upstream
and fedora rawhide! Thanks!


 The code I see in NSS seems to assume there is only one SAN section? I
 checked and it does not create one big list of all the SAN extensions,
 because I don't see my IP address SAN in the above example.


It doesn't. For most of NSS we usually are looking for a specific SAN (like a 
particular DNS name, or an email address.), so it loops through them all.


I'm surprised the SAN processing isn't exported since applications that 
override the SSL name check would need it.


You do export CERT_VerifyCertName() which uses this function. So maybe I
was trying to use the wrong function. But it seems this function also
does not process multiple subjectAltName sections.


 - While browsing through some code for this, I noticed:

 if (!!(nameList = CERT_DecodeAltNameExtension(tmpArena,
 ))) {
 CERTGeneralName *current = nameList;

 I'm a little confused about the double exclamation mark? I hope it is
 something clever and not a typo?
It looks correct but funky. The if clearly should trigger if nameList is 
non-zero. It looks to me like a bad attempt to silence a compiler warning (I 
personally prefer coding (xxx = func) != NULL). I suspect the original code 
was:

   if (nameList = CERT_DecodeAltNameExtension(tmpArea,))  {
Which triggered the normal compiler warning to protect agains things like: if 
(nameList = NULL) instead of if (nameList == NULL).


Okay, that is what i thought, but i just wanted to be sure "!!" was not
a bad typo.

Paul
--
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto


Re: How to get a list of SubjectAltNames of a cert in NSS

2017-02-23 Thread John Dennis

Argh ... looks like the mailing list scrubbed 2 of my attachments.
Here is the python code (not as an attachment), hope the mailer does not 
mangle it.


import sys
import nss.nss as nss
from nss.error import NSPRError

# Perform basic configuration and setup
nss.nss_init_nodb()

# Get the cert filename from command line argument
filename = sys.argv[1]
print "certificate filename: %s" % (filename)

# Read the certificate from the file
si = nss.read_der_from_file(filename, True)

# Parse the DER encoded data returning a Certificate object
cert = nss.Certificate(si)

# Get the SubjectAltName extension from the cert
try:
extension = cert.get_extension(nss.SEC_OID_X509_SUBJECT_ALT_NAME)
except KeyError:
print "Certificate does not contain a SubjectAltName extension"
sys.exit(1)

# Get the names from the extension
names = nss.x509_alt_name(extension.value)

# Print out the names
print 'certificate subject: %s' % cert.subject
print 'has %d alternate names' % len(names)
for name in names:
print '  %s' % name

# Success
sys.exit(0)



--
John
--
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto


Re: How to get a list of SubjectAltNames of a cert in NSS

2017-02-23 Thread John Dennis

On 02/23/2017 11:14 AM, John Dennis wrote:

On 02/23/2017 11:04 AM, Paul Wouters wrote:


Hi,

I'm looking at the best way to get a list of SubjectAltNames of a
CERTCertificate.

Anyone have a pointer (haha) for me ?


CERT_DecodeAltNameExtension

See secu_PrintAltNameExtension() in cmd/lib/secutil.c or
cert_VerifySubjectAltName() in lib/certdb/certdb.c for an examples.


Actually, if all you want to simply grab the names avoiding C code you 
can use the nss python binding. Attached is a simple Python script, the 
Symantec cert to use as an example, and the output of the script


% python nss_print_subject_alt_names.py symantec.pem




--
John
certificate filename: symantec.pem
certificate subject: CN=www.symantec.com,OU=Corp Mktg & Comms - Online 
Exp,O=Symantec Corporation,STREET=350 Ellis Street,L=Mountain 
View,ST=California,postalCode=94043,C=US,serialNumber=2158113,businessCategory=Private
 Organization,incorporationState=Delaware,incorporationCountry=US
has 25 alternate names
  partnernet.symantec.com
  partnernet-internal.symantec.com
  sites-internal.symantec.com
  www.go.symantec.com
  www4.symantec.com
  sites.symantec.com
  sites-qa.symantec.com
  my-qa.symantec.com
  bcportal.symantec.com
  partnernet.norton.com
  scm.symantec.com
  partnernet-internal.norton.com
  partnernet-uat.symantec.com
  securityresponse.symantec.com
  my.symantec.com
  go.symantec.com
  sites-uat.symantec.com
  partnernet-qa.symantec.com
  partnernet-uat.norton.com
  partnernet-qa.norton.com
  partnernet-sit.symantec.com
  www.symantec.com
  m.symantec.com
  partnernet-temp.symantec.com
  my-uat.symantec.com
-- 
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Re: How to get a list of SubjectAltNames of a cert in NSS

2017-02-23 Thread John Dennis

On 02/23/2017 11:04 AM, Paul Wouters wrote:


Hi,

I'm looking at the best way to get a list of SubjectAltNames of a
CERTCertificate.

Anyone have a pointer (haha) for me ?


CERT_DecodeAltNameExtension

See secu_PrintAltNameExtension() in cmd/lib/secutil.c or 
cert_VerifySubjectAltName() in lib/certdb/certdb.c for an examples.



--
John
--
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto


How to get a list of SubjectAltNames of a cert in NSS

2017-02-23 Thread Paul Wouters


Hi,

I'm looking at the best way to get a list of SubjectAltNames of a 
CERTCertificate.

Anyone have a pointer (haha) for me ?

Paul
--
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto