1111using Microsoft . Extensions . Logging ;
1212using Microsoft . Extensions . Logging . Abstractions ;
1313using Microsoft . VisualBasic ;
14+ using Microsoft . Win32 . SafeHandles ;
1415
1516using Newtonsoft . Json ;
1617
@@ -70,11 +71,12 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
7071 CertCentralCertType certType = CertCentralCertType . GetAllTypes ( _config ) . FirstOrDefault ( x => x . ProductCode . Equals ( productInfo . ProductID ) ) ;
7172 OrderRequest orderRequest = new OrderRequest ( certType ) ;
7273
73- //var days = (productInfo.ProductParameters.ContainsKey("LifetimeDays") && !st) ? int.Parse(productInfo.ProductParameters["LifetimeDays"]) : 365;
74+ string typeOfCert = ( productInfo . ProductParameters . ContainsKey ( CertCentralConstants . Config . CERT_TYPE ) ) ? productInfo . ProductParameters [ CertCentralConstants . Config . CERT_TYPE ] . ToLower ( ) : "ssl" ;
75+
7476 var days = 365 ;
75- if ( productInfo . ProductParameters . ContainsKey ( "LifetimeDays" ) && ! string . IsNullOrEmpty ( productInfo . ProductParameters [ "LifetimeDays" ] ) )
77+ if ( productInfo . ProductParameters . ContainsKey ( CertCentralConstants . Config . LIFETIME ) && ! string . IsNullOrEmpty ( productInfo . ProductParameters [ CertCentralConstants . Config . LIFETIME ] ) )
7678 {
77- days = int . Parse ( productInfo . ProductParameters [ "LifetimeDays" ] ) ;
79+ days = int . Parse ( productInfo . ProductParameters [ CertCentralConstants . Config . LIFETIME ] ) ;
7880 }
7981 int validityYears = 0 ;
8082 DateTime ? customExpirationDate = null ;
@@ -90,16 +92,31 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
9092 break ;
9193 }
9294
95+ // Convert to case-insensitive dictionary
96+ Dictionary < string , string [ ] > sandict = new Dictionary < string , string [ ] > ( StringComparer . OrdinalIgnoreCase ) ;
97+ foreach ( var s in san )
98+ {
99+ sandict . Add ( s . Key , s . Value ) ;
100+ }
101+
93102 List < string > dnsNames = new List < string > ( ) ;
94- if ( san . ContainsKey ( "Dns" ) )
103+ List < string > emails = new List < string > ( ) ;
104+ if ( sandict . ContainsKey ( "Dns" ) )
95105 {
96106 dnsNames = new List < string > ( san [ "Dns" ] ) ;
97107 }
98-
99- if ( san . ContainsKey ( "dnsname" ) )
108+ if ( sandict . ContainsKey ( "dnsname" ) )
100109 {
101110 dnsNames = new List < string > ( san [ "dnsname" ] ) ;
102111 }
112+ if ( sandict . ContainsKey ( "Email" ) )
113+ {
114+ emails = new List < string > ( san [ "Email" ] ) ;
115+ }
116+ if ( sandict . ContainsKey ( "Rfc822Name" ) )
117+ {
118+ emails = new List < string > ( san [ "Rfc822Name" ] ) ;
119+ }
103120
104121 X509Name subjectParsed = null ;
105122 string commonName = null , organization = null , orgUnit = null ;
@@ -114,13 +131,24 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
114131
115132 if ( commonName == null )
116133 {
117- if ( dnsNames . Count > 0 )
134+ if ( typeOfCert . Equals ( "ssl" ) && dnsNames . Count > 0 )
118135 {
119136 commonName = dnsNames [ 0 ] ;
120137 }
138+ else if ( typeOfCert . Equals ( "client" ) && emails . Count > 0 )
139+ {
140+ commonName = emails [ 0 ] ;
141+ }
121142 else
122143 {
123- throw new Exception ( "No Common Name or DNS SAN provided, unable to enroll" ) ;
144+ throw new Exception ( "No Common Name or SAN provided, unable to enroll" ) ;
145+ }
146+ }
147+ else
148+ {
149+ if ( typeOfCert . Equals ( "client" ) && emails . Count == 0 )
150+ {
151+ emails . Add ( commonName ) ;
124152 }
125153 }
126154
@@ -190,7 +218,14 @@ public async Task<EnrollmentResult> Enroll(string csr, string subject, Dictionar
190218 orderRequest . Certificate . CommonName = commonName ;
191219 orderRequest . Certificate . CSR = csr ;
192220 orderRequest . Certificate . SignatureHash = signatureHash ;
193- orderRequest . Certificate . DNSNames = dnsNames ;
221+ if ( typeOfCert . Equals ( "ssl" ) )
222+ {
223+ orderRequest . Certificate . DNSNames = dnsNames ;
224+ }
225+ else if ( typeOfCert . Equals ( "client" ) )
226+ {
227+ orderRequest . Certificate . Emails = emails ;
228+ }
194229 orderRequest . Certificate . CACertID = caCertId ;
195230 orderRequest . SetOrganization ( organizationId ) ;
196231 if ( ! string . IsNullOrEmpty ( orgUnit ) )
@@ -524,6 +559,13 @@ public Dictionary<string, PropertyConfigInfo> GetTemplateParameterAnnotations()
524559 Hidden = false ,
525560 DefaultValue = 90 ,
526561 Type = "Number"
562+ } ,
563+ [ CertCentralConstants . Config . CERT_TYPE ] = new PropertyConfigInfo ( )
564+ {
565+ Comments = "OPTIONAL: The type of cert to enroll for. Valid values are 'ssl' and 'client'. The value provided here must be consistant with the ProductID. If not provided, default is 'ssl'." ,
566+ Hidden = false ,
567+ DefaultValue = "ssl" ,
568+ Type = "String"
527569 }
528570 } ;
529571 }
@@ -864,6 +906,15 @@ public async Task ValidateProductInfo(EnrollmentProductInfo productInfo, Diction
864906 }
865907 CertCentralClient client = new CertCentralClient ( apiKey , region ) ;
866908
909+ if ( connectionInfo . ContainsKey ( CertCentralConstants . Config . CERT_TYPE ) )
910+ {
911+ var typeOfCert = ( string ) connectionInfo [ CertCentralConstants . Config . CERT_TYPE ] ;
912+ if ( ! ( typeOfCert . Equals ( "ssl" ) || typeOfCert . Equals ( "client" ) ) )
913+ {
914+ throw new Exception ( "Invalid Cert Type specified. Valid options are 'ssl' or 'client'" ) ;
915+ }
916+ }
917+
867918 // Get the available types and check that it's one of them.
868919 // We're doing this because to get the list of valid product IDs in a comment, the user must have at least one correct product/template mapping.
869920 // We therefore need to have some way of telling them what the valid product IDs are to begin with.
0 commit comments