@@ -160,8 +160,34 @@ public static string GetSubjectName (this X509Certificate certificate)
160
160
return certificate . GetSubjectNameInfo ( X509Name . Name ) ;
161
161
}
162
162
163
+ static string [ ] GetSubjectAlternativeNames ( X509Certificate certificate , int tagNo )
164
+ {
165
+ var alt = certificate . GetExtensionValue ( X509Extensions . SubjectAlternativeName ) ;
166
+
167
+ if ( alt == null )
168
+ return Array . Empty < string > ( ) ;
169
+
170
+ var seq = Asn1Sequence . GetInstance ( Asn1Object . FromByteArray ( alt . GetOctets ( ) ) ) ;
171
+ var names = new string [ seq . Count ] ;
172
+ int count = 0 ;
173
+
174
+ foreach ( Asn1Encodable encodable in seq ) {
175
+ var name = GeneralName . GetInstance ( encodable ) ;
176
+ if ( name . TagNo == tagNo )
177
+ names [ count ++ ] = ( ( IAsn1String ) name . Name ) . GetString ( ) ;
178
+ }
179
+
180
+ if ( count == 0 )
181
+ return Array . Empty < string > ( ) ;
182
+
183
+ if ( count < names . Length )
184
+ Array . Resize ( ref names , count ) ;
185
+
186
+ return names ;
187
+ }
188
+
163
189
/// <summary>
164
- /// Gets the subject email address of the certificate.
190
+ /// Get the subject email address of the certificate.
165
191
/// </summary>
166
192
/// <remarks>
167
193
/// The email address component of the certificate's Subject identifier is
@@ -170,31 +196,54 @@ public static string GetSubjectName (this X509Certificate certificate)
170
196
/// </remarks>
171
197
/// <returns>The subject email address.</returns>
172
198
/// <param name="certificate">The certificate.</param>
199
+ /// <param name="idnEncode">If set to <c>true</c>, international edomain names will be IDN encoded.</param>
173
200
/// <exception cref="System.ArgumentNullException">
174
201
/// <paramref name="certificate"/> is <see langword="null"/>.
175
202
/// </exception>
176
- public static string GetSubjectEmailAddress ( this X509Certificate certificate )
203
+ public static string GetSubjectEmailAddress ( this X509Certificate certificate , bool idnEncode = false )
177
204
{
178
205
var address = certificate . GetSubjectNameInfo ( X509Name . EmailAddress ) ;
179
206
180
- if ( ! string . IsNullOrEmpty ( address ) )
181
- return address ;
182
-
183
- var alt = certificate . GetExtensionValue ( X509Extensions . SubjectAlternativeName ) ;
207
+ if ( string . IsNullOrEmpty ( address ) ) {
208
+ var addresses = GetSubjectAlternativeNames ( certificate , GeneralName . Rfc822Name ) ;
184
209
185
- if ( alt == null )
186
- return string . Empty ;
210
+ if ( addresses . Length > 0 )
211
+ address = addresses [ 0 ] ;
212
+ }
187
213
188
- var seq = Asn1Sequence . GetInstance ( Asn1Object . FromByteArray ( alt . GetOctets ( ) ) ) ;
214
+ if ( idnEncode && ! string . IsNullOrEmpty ( address ) )
215
+ address = MailboxAddress . EncodeAddrspec ( address ) ;
189
216
190
- foreach ( Asn1Encodable encodable in seq ) {
191
- var name = GeneralName . GetInstance ( encodable ) ;
217
+ return address ;
218
+ }
192
219
193
- if ( name . TagNo == GeneralName . Rfc822Name )
194
- return ( ( IAsn1String ) name . Name ) . GetString ( ) ;
220
+ /// <summary>
221
+ /// Get the subject domain names of the certificate.
222
+ /// </summary>
223
+ /// <remarks>
224
+ /// <para>Gets the subject DNS names of the certificate.</para>
225
+ /// <para>Some S/MIME certificates are domain-bound instead of being bound to a
226
+ /// particular email address.</para>
227
+ /// </remarks>
228
+ /// <returns>The subject DNS names.</returns>
229
+ /// <param name="certificate">The certificate.</param>
230
+ /// <param name="idnEncode">If set to <c>true</c>, international domain names will be IDN encoded.</param>
231
+ /// <exception cref="System.ArgumentNullException">
232
+ /// <paramref name="certificate"/> is <see langword="null"/>.
233
+ /// </exception>
234
+ public static string [ ] GetSubjectDnsNames ( this X509Certificate certificate , bool idnEncode = false )
235
+ {
236
+ var domains = GetSubjectAlternativeNames ( certificate , GeneralName . DnsName ) ;
237
+
238
+ if ( idnEncode ) {
239
+ for ( int i = 0 ; i < domains . Length ; i ++ )
240
+ domains [ i ] = MailboxAddress . IdnMapping . Encode ( domains [ i ] ) ;
241
+ } else {
242
+ for ( int i = 0 ; i < domains . Length ; i ++ )
243
+ domains [ i ] = MailboxAddress . IdnMapping . Decode ( domains [ i ] ) ;
195
244
}
196
245
197
- return null ;
246
+ return domains ;
198
247
}
199
248
200
249
internal static string AsHex ( this byte [ ] blob )
0 commit comments