#506 SubjectAltNameExtDefault: createExtension gname with escaped chars exception - Unknown AVA keyword 'CN\'
Closed: migrated by dmoluguw. Opened by nkinder.

Description of problem:

Certificate enrollment to initialize a subject alternative name with multiple
AVAs read from LDAP is failing with an exception.
The SAN's type is a DirectoryName as a DN, with multiuple AVAs, and that DN
information is not passed in the request as paramaters of the HTTP POST, nor as
user defined extensions into the CSR, the requirement is to read the DN that
will go into the subjAltExtPattern from LDAP.

In this scenario, because there is no apparent LDAP params support for
subjectAltNameExtDefaultImpl
(there will be a separate BZ for the LDAP configuration in profiles)
the "workaround is to use nsTokenUserKeySubjectNameDefault with LDAP
configuration, which "accidently" become available to
subjectAltNameExtDefaultImpl

The DN is correctly read from LDAP, and the general name is escaped like for
example:
nsTokenUserKeySubjectNameDefault: getSubjectName(): got attribute:
pkisponsordn=cn\=cnguest1\,ou\=people\,dc\=example\,dc\=com

But the problem is shortly after, when that escaped DN is rejected in
SubjectAltNameExtDefault:
SubjectAltNameExtDefault: createExtension got
gname=cn\=cnguest1\,ou\=people\,dc\=example\,dc\=com
SubjectAltNameExtDefault: populate java.io.IOException: Unknown AVA keyword
'CN\'.
SubjectAltNameExtDefault: populate sees no extension. get out

If I try passing the DN as a parameter to the HTTP POST with the CSR, or
placing various attributes instead of a full DN in the profile's
default.params.subjAltExtPattern_0, like for example:
policyset.userCertSet.8.default.params.subjAltExtType_0=DirectoryName
policyset.userCertSet.8.default.params.subjAltExtPattern_0=cn=$request.cn$,ou=$
request.roomNumber$,ou=$request.carLicense$,ou=people,dc=example,dc=com

All attributes are properly read and populated in the request to the agent,
without escaping, liek for example:

[30/Jan/2013:09:21:34]http-8443-Processor25: SubjectAltNameExtDefault:
getValue append GN:DirectoryName:
CN=cnguest2,OU=0123456789,OU=6ZBC246,OU=people,DC=example,DC=com
[30/Jan/2013:09:21:34]http-8443-Processor25: CMSServlet: curDate=Wed Jan 30
09:21:34 PST 2013 id=caProfileReview time=191

But the agent interface complains without an exception and finishes with
"ProfileProcessServlet: execution error Invalid Property dnpattern", when gname
and subjAltNames are null, no other details, for example:

[30/Jan/2013:09:24:03]http-8443-Processor24: ProfileProcessServlet:
profileId=caUserCertTEST
[30/Jan/2013:09:24:03]http-8443-Processor24:
nsTokenUserKeySubjectNameDefault: in setValue, value=null
[30/Jan/2013:09:24:03]http-8443-Processor24: ProfileProcessServlet: execution
error Invalid Property dnpattern
[30/Jan/2013:09:24:03]http-8443-Processor24: CMSServlet: curDate=Wed Jan 30
09:24:03 PST 2013 id=caProfileProcess time=113

so nsTokenUserKeySubjectNameDefault: getSubjectName
escapes the DN
and SubjectAltNameExtDefault: getValue
does not escapes the DN for the gname with DirectoryName
and SubjectAltNameExtDefault does not like escaped DNs

files
./pki/base/common/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.jav
a
./pki/base/common/src/com/netscape/cms/profile/def/nsTokenUserKeySubjectNameDef
ault.java
./pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java

Steps to Reproduce:

  1. prepare LDAP user backend

1.a custom schema, could probably used esixiting schema

vi /etc/dirsrv/slapd-dirsec3-seg/schema/99user.ldif
attributetypes: ( 2.16.840.1133730.2.12345 NAME 'pkisponsordn' DESC 'test pki
sponsor dn' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128}
X-ORIGIN 'Example defined' )
attributetypes: ( 1.2.3.4.5.6.1 NAME 'dateofbirth' DESC 'For employee
birthdays' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUED X-ORIGIN 'Example
defined')
objectclasses: ( 1.2.3.4.5.6.7.1 NAME 'pkisponsor' DESC 'test pki sponsor' SUP
top AUXILIARY MUST cn MAY (dateofbirth $ preferredLanguage $ pkisponsordn) )

/etc/init.d/dirsrv restart dirsec3-seg

1.b user data

see attachment cnguest1.cnguest2.ldif
or use 10.14.7.222 -p 389 -b dc=example,dc=com

basically has 2 users entries

dn: cn=cnguest1,ou=people,dc=example,dc=com

and

ldapsearch -xLLL -h 10.14.7.222 -p 389 -b dc=example,dc=com uid=cnguest2 dn uid
cn roomNumber carLicense pkisponsordn

dn: uid=cnguest2,ou=people,dc=example,dc=com
uid: cnguest2
cn: cnguest2
roomNumber: 0123456789
carLicense: 6ZBC246
pkisponsordn: cn=cnguest1,ou=people,dc=example,dc=com

  1. prepare a test profile

see attachment caUserCertTEST.cfg

has some generic inputs, but they are not needed when fectching from LDAP

important part is
policyset.userCertSet.1.default.class_id=nsTokenUserKeySubjectNameDefaultImpl
policyset.userCertSet.1.default.params.ldapStringAttributes=uid,cn,roomNumber,c
arLicense,pkisponsordn
and
policyset.userCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
policyset.userCertSet.8.default.params.subjAltExtPattern_0=$request.pkisponsord
n$

some more details:

policyset.userCertSet.1.default.class_id=nsTokenUserKeySubjectNameDefaultImpl
policyset.userCertSet.1.default.name=nsTokenUserKeySubjectNameDefault
policyset.userCertSet.1.default.params.dnpattern=cn=$request.cn$,ou=$request.ro
omNumber$,ou=people,dc=example,dc=com
policyset.userCertSet.1.default.params.ldap.enable=true
policyset.userCertSet.1.default.params.ldap.searchName=uid

Set the variables we will be pulling from the ldap directory.

policyset.userCertSet.1.default.params.ldapStringAttributes=uid,cn,roomNumber,c
arLicense,pkisponsordn

basedn is the scheme the data is pulled from, need to check on what it should

be.
policyset.userCertSet.1.default.params.ldap.basedn=ou=people,dc=example,dc=com
policyset.userCertSet.1.default.params.ldap.maxConns=4
policyset.userCertSet.1.default.params.ldap.minConns=1

specifies location of the DS. This will have to change when deployed

policyset.userCertSet.1.default.params.ldap.ldapconn.host=10.14.7.222
policyset.userCertSet.1.default.params.ldap.ldapconn.port=389
policyset.userCertSet.1.default.params.ldap.ldapconn.secureConn=false
policyset.userCertSet.1.default.params.ldap.ldapconn.Version=3

and

policyset.userCertSet.8.constraint.class_id=noConstraintImpl
policyset.userCertSet.8.constraint.name=No Constraint
policyset.userCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
policyset.userCertSet.8.default.name=Subject Alternative Name Extension Default
policyset.userCertSet.8.default.params.subjAltNameExtCritical=false
policyset.userCertSet.8.default.params.subjAltNameNumGNs=1
policyset.userCertSet.8.default.params.subjAltExtGNEnable_0=true

policyset.userCertSet.8.default.params.subjAltExtType_0=RFC822Name

policyset.userCertSet.8.default.params.subjAltExtPattern_0=$request.requestor

_email$
policyset.userCertSet.8.default.params.subjAltExtType_0=DirectoryName
policyset.userCertSet.8.default.params.subjAltExtPattern_0=$request.pkisponsord
n$

policyset.userCertSet.8.default.params.subjAltExtPattern_0=cn=$request.cn$,ou

=$request.roomNumber$,ou=$request.carLicense$,ou=people,dc=example,dc=com

  1. enroll using EE interface

https://ca1.example.com:8444/ca/ee/ca/profileSelect?profileId=caUserCertTEST

example request, subject will be changed, so it does no really matter:
Subject: C=US, ST=Example, L=ExampleLocality, O=ExampleOrg,
OU=ExampleOU, CN=www.example.com/emailAddress=test@example.com/UID=cnguest2

-----BEGIN CERTIFICATE REQUEST-----
MIIEMDCCAxgCAQAwgbcxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdFeGFtcGxlMRgw
FgYDVQQHEw9FeGFtcGxlTG9jYWxpdHkxEzARBgNVBAoTCkV4YW1wbGVPcmcxEjAQ
BgNVBAsTCUV4YW1wbGVPVTEYMBYGA1UEAxMPd3d3LmV4YW1wbGUuY29tMR8wHQYJ
KoZIhvcNAQkBFhB0ZXN0QGV4YW1wbGUuY29tMRgwFgYKCZImiZPyLGQBARMIY25n
dWVzdDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKVvEBp+zPu2df
1ps/UlV3sWolBq3J77KpBN0sLh1qiUFfA3ycXXFUCxS9ZGd6NLdzVC3hCDFJDclP
NeMyTaBgeoPowJ5bZ0gEAZ86DJfYucdbFJ4AN547ZTcwDQmz4EmhNuoTv2895qf/
GJnNYX0pM2EhufB0gKuXutiK4VgrmGCMtDw5/uMFCsFZggacRyR/Nr8z22P7Gk16
OChnQjJujF5lrbh0dhxlGBzlbgsf1jjwGMA+oRhpWfwVnx0I80SMlgS3mnK4wy3b
1S9/+b4vkPIvuS+E47BRLSdccd+7QkkMN/W80fz75/gxc7KCBMZWC7jEKmnHzIxd
Xb/z4BsXAgMBAAGgggExMIIBLQYJKoZIhvcNAQkOMYIBHjCCARowggEWBgNVHREE
ggENMIIBCaArBgorBgEEAYI3FAIDoB0MG2JvYk90aGVyQWx0TmFtZUBleGFtcGxl
LmNvbYEcYm9iUkZDODIyQWx0TmFtZUBleGFtcGxlLmNvbYIMZXhhbXBsZTEuY29t
ggxleGFtcGxlMi5jb22GE2h0dHA6Ly9leGFtcGxlLmNvbS+HEAATAAAAAAAAAAAA
AAAAABeHBMCoBwGkczBxMQswCQYDVQQGEwJVUzETMBEGA1UEChMKR29sZCBNdXNp
YzEVMBMGA1UECxMMR29sZCBCYWxsYWRzMQwwCgYDVQQDEwNib2IxKDAmBgkqhkiG
9w0BCQEWGWJvYkRpckFsdE5hbWVAZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQAD
ggEBAEB9BtjxcXgO1+5QYVqaDIgVplJ0J61VpQVG2id+Lx+VzRZm5e01u2pgJidE
EUADXFs4YaG9E0OMQvD6Z7zq28YYRPPjIIiLfBynv47Ev1nPzmUw0CX1UwK/uPjp
dO6xn0a8zUSqIjJ4D9opgTU+MhCmyA1bbgNf2pxvU0Amsi04NTcO0DEWRzKoKWxg
5O9mnXXAgsXr9kEgWKq5asMp5SZhpdzriLgOHKCZQpWB1Tlje2JIWuUw4N8wL0Rq
uzYDkKi6C3HnJR5KKftmN9J1BcHbla8LjvC4YhAr5JKN3t6MqfOKdMsyMnrgemUP
tSAi/IzCfmxrCXiE5G5QFeFT2t4=
-----END CERTIFICATE REQUEST-----

Actual results:

upon EE service submission, LDAP access log, good search:

[30/Jan/2013:03:30:33 -0800] conn=8 op=0 SRCH
base="ou=people,dc=example,dc=com" scope=2 filter="(uid=cnguest2)" attrs=ALL
[30/Jan/2013:03:30:33 -0800] conn=8 op=0 RESULT err=0 tag=101 nentries=1
etime=0
[30/Jan/2013:03:30:33 -0800] conn=8 op=1 SRCH
base="uid=cnguest2,ou=people,dc=example,dc=com" scope=0
filter="(objectClass=*)" attrs="uid cn roomNumber carLicense pkisponsordn"
[30/Jan/2013:03:30:33 -0800] conn=8 op=1 RESULT err=0 tag=101 nentries=1
etime=0
[30/Jan/2013:03:30:33 -0800] conn=8 op=2 UNBIND

in CA debug log, pkisponsordn is escaped in nsTokenUserKeySubjectNameDefault:
getSubjectName:

...
[30/Jan/2013:10:29:55]http-8444-Processor25:
nsTokenUserKeySubjectNameDefault: getSubjectName(): got LDAP connection
[30/Jan/2013:10:29:55]http-8444-Processor25:
nsTokenUserKeySubjectNameDefault: getSubjectName(): about to search with basedn
= ou=people,dc=example,dc=com
[30/Jan/2013:10:29:55]http-8444-Processor25:
nsTokenUserKeySubjectNameDefault: getSubjectName(): retrieved entry for uid =
cnguest2
[30/Jan/2013:10:29:55]http-8444-Processor25:
nsTokenUserKeySubjectNameDefault: getSubjectName(): about to search with 5
attributes
[30/Jan/2013:10:29:55]http-8444-Processor25:
nsTokenUserKeySubjectNameDefault: getSubjectName(): got attribute: uid=cnguest2
[30/Jan/2013:10:29:55]http-8444-Processor25:
nsTokenUserKeySubjectNameDefault: getSubjectName(): got attribute: cn=cnguest2
[30/Jan/2013:10:29:55]http-8444-Processor25:
nsTokenUserKeySubjectNameDefault: getSubjectName(): got attribute:
roomNumber=0123456789
[30/Jan/2013:10:29:55]http-8444-Processor25:
nsTokenUserKeySubjectNameDefault: getSubjectName(): got attribute:
carLicense=6ZBC246
[30/Jan/2013:10:29:55]http-8444-Processor25:
nsTokenUserKeySubjectNameDefault: getSubjectName(): got attribute:
pkisponsordn=cn\=cnguest1\,ou\=people\,dc\=example\,dc\=com
[30/Jan/2013:10:29:55]http-8444-Processor25: pattern =
cn=$request.cn$,ou=$request.roomNumber$,ou=people,dc=example,dc=com
[30/Jan/2013:10:29:55]http-8444-Processor25:
nsTokenUserKeySubjectNameDefault: getSubjectName(): subject name mapping done
[30/Jan/2013:10:29:55]http-8444-Processor25:
nsTokenUserKeySubjectNameDefault: getSubjectName(): attributes set in request
[30/Jan/2013:10:29:55]http-8444-Processor25: returnConn: mNumConns now 0
[30/Jan/2013:10:29:55]http-8444-Processor25:
subjectName=cn=cnguest2,ou=0123456789,ou=people,dc=example,dc=com
[30/Jan/2013:10:29:55]http-8444-Processor25:
nsTokenUserKeySubjectNameDefault: populate end

and the "SubjectAltNameExtDefault: createExtension got gname" does not like
this:

...
[30/Jan/2013:10:29:55]http-8444-Processor25: SubjectAltNameExtDefault:
populate start
[30/Jan/2013:10:29:55]http-8444-Processor25: SubjectAltNameExtDefault:
createExtension i=0
[30/Jan/2013:10:29:55]http-8444-Processor25: SubjectAltNameExtDefault:
createExtension got gname=cn\=cnguest1\,ou\=people\,dc\=example\,dc\=com
[30/Jan/2013:10:29:55]http-8444-Processor25: SubjectAltNameExtDefault:
populate java.io.IOException: Unknown AVA keyword 'CN\'.
[30/Jan/2013:10:29:55]http-8444-Processor25: SubjectAltNameExtDefault:
populate sees no extension. get out
[30/Jan/2013:10:29:55]http-8444-Processor25: SubjectAltNameExtDefault:
populate end
[30/Jan/2013:10:29:55]http-8444-Processor25: SigningAlgDefault: populate
start
[30/Jan/2013:10:29:55]http-8444-Processor25: SigningAlgDefault: populate end
[30/Jan/2013:10:29:55]http-8444-Processor25: CMSServlet: in auditSubjectID
[30/Jan/2013:10:29:55]http-8444-Processor25: CMSServlet: auditSubjectID
auditContext {sslClientCertProvider=com.netscape.cms.servlet.profile.SSLClientC
ertProvider@ed0f59e,
profileContext=com.netscape.cms.profile.common.EnrollProfileContext@38ad5fab}
[30/Jan/2013:10:29:55]http-8444-Processor25: CMSServlet auditSubjectID:
subjectID: null
[30/Jan/2013:10:29:55]http-8444-Processor25: ProfileSubmitServlet:
key=$request.roomnumber$ value=0123456789
[30/Jan/2013:10:29:55]http-8444-Processor25: ProfileSubmitServlet:
key=$request.profileapprovedby$ value=admin
[30/Jan/2013:10:29:55]http-8444-Processor25: ProfileSubmitServlet:
key=$request.pkisponsordn$ value=cn\=cnguest1\,ou\=people\,dc\=example\,dc\=com
[30/Jan/2013:10:29:55]http-8444-Processor25: ProfileSubmitServlet:
key=$request.cert_request$ value=-----BEGIN CERTIFICATE REQUEST-----
MIIEMDCCAxgCAQAwgbcxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdFeGFtcGxlMRgw

when the agent interface is accessed, the gname seem null:

[30/Jan/2013:10:30:23]http-8443-Processor25: SubjectAltNameExtDefault:
createExtension i=0
[30/Jan/2013:10:30:23]http-8443-Processor25: gname is empty, not added
[30/Jan/2013:10:30:23]http-8443-Processor25: count is 0
[30/Jan/2013:10:30:23]http-8443-Processor25: SubjectAltNameExtDefault:
populate sees no extension. get out
[30/Jan/2013:10:30:23]http-8443-Processor25: SubjectAltNameExtDefault:
createExtension i=0
[30/Jan/2013:10:30:23]http-8443-Processor25: gname is empty, not added
[30/Jan/2013:10:30:23]http-8443-Processor25: count is 0
[30/Jan/2013:10:30:23]http-8443-Processor25: SubjectAltNameExtDefault:
populate sees no extension. get out
[30/Jan/2013:10:30:23]http-8443-Processor25: CMSServlet: curDate=Wed Jan 30
10:30:23 PST 2013 id=caProfileReview time=260

and it got:
pkisponsordn pkisponsordn cn\=cnguest1\,ou\=people\,dc\=example\,dc\=com

This default populates a Subject Alternative Name Extension (2.5.29.17) to the
request. The default values are Criticality=false, Record

0{Pattern:$request.pkisponsordn$,Pattern Type:DirectoryName,Enable:true}

with
Criticality: false
General Names: null

and then upon agent approval:

[30/Jan/2013:10:37:33]http-8443-Processor24: ProfileProcessServlet:
profileId=caUserCertTEST
[30/Jan/2013:10:37:33]http-8443-Processor24:
nsTokenUserKeySubjectNameDefault: in setValue, value=null
[30/Jan/2013:10:37:33]http-8443-Processor24: ProfileProcessServlet: execution
error Invalid Property dnpattern
[30/Jan/2013:10:37:33]http-8443-Processor24: CMSServlet: curDate=Wed Jan 30
10:37:33 PST 2013 id=caProfileProcess time=120

Error Reason: Property Error - Invalid Property dnpattern


proposed Milestone: 10.2.3 - Per Dogtag 10.2.3 meeting of 09/25/2014

Per Dogtag 10.2.X meeting of 01/14/2015: Milestone 10.2.2

Per 10.2.2 Triage meeting of 02/24/2015: 10.3

Metadata Update from @nkinder:
- Issue assigned to cfu
- Issue set to the milestone: UNTRIAGED

Dogtag PKI is moving from Pagure issues to GitHub issues. This means that existing or new
issues will be reported and tracked through Dogtag PKI's GitHub Issue tracker.

This issue has been cloned to GitHub and is available here:
https://github.com/dogtagpki/pki/issues/1076

If you want to receive further updates on the issue, please navigate to the
GitHub issue and click on Subscribe button.

Thank you for understanding, and we apologize for any inconvenience.

Metadata Update from @dmoluguw:
- Issue close_status updated to: migrated
- Issue status updated to: Closed (was: Open)

Metadata