Retired Microsoft Blog disclaimer

This directory is a mirror of retired "Decrypt My World" MSDN blog and is provided as is. All posting authorship and copyrights belong to respective authors.

Posts on this page:

Original URL: https://blogs.msdn.microsoft.com/alejacma/2011/11/07/how-to-add-alternative-directory-name-to-your-certificate-request-c/
Post name: How to add Alternative Directory Name to your certificate request (C#)
Original author: Alejandro Campos Magencio
Posting date: 2011-11-07T07:01:44+00:00


Hi all,

We've already seen How to add Subject Alternative Name to your certificate requests (C#). What if we want to set Alternative Directory Name (XCN_CERT_ALT_NAME_DIRECTORY_NAME) in addition to Subject Alternative Name (XCN_CERT_ALT_NAME_RFC822_NAME)?

The interface we use for the alternative names has different methods that we can use depending on the value we want to set:

IAlternativeName interface
"
You can initialize an IAlternativeName object from an AlternativeNameType enumeration. The following types are available, but they are supported by different initialization methods as indicated.

Value: XCN_CERT_ALT_NAME_RFC822_NAME
Description: The name is an email address.
Initialization method: InitializeFromString

Value: XCN_CERT_ALT_NAME_DIRECTORY_NAME
Description: The name is an X.500 directory name.
Initialization method: InitializeFromRawData
"

The C# code to set both Subject Alternative Name and Alternative Directory Name should look like this then:

 string strRfc822Name = "myuser@mydomain.com"; 
 string strDirectoryName = "CN=myuser"; 
 ... 
 CAlternativeName objRfc822Name = new CAlternativeName(); 
 CX500DistinguishedName objX500 = new CX500DistinguishedName(); 
 string strDirectory = null; 
 CAlternativeName objDirectoryName = new CAlternativeName(); 
 CAlternativeNames objAlternativeNames = new CAlternativeNames(); 
 CX509ExtensionAlternativeNames objExtensionAlternativeNames = new CX509ExtensionAlternativeNames(); 
 ... 
 
 // Set Alternative RFC822 Name 
 objRfc822Name.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_RFC822_NAME, strRfc822Name); 
 
 // Set Alternative Directory Name 
 objX500.Encode(strDirectoryName, X500NameFlags.XCN_CERT_NAME_STR_FORCE_UTF8_DIR_STR_FLAG); 
 strDirectory = objX500.get_EncodedName(EncodingType.XCN_CRYPT_STRING_BINARY); 
 objDirectoryName.InitializeFromRawData(AlternativeNameType.XCN_CERT_ALT_NAME_DIRECTORY_NAME, EncodingType.XCN_CRYPT_STRING_BINARY, strDirectory); 
 
 // Set Alternative Names 
 objAlternativeNames.Add(objRfc822Name); 
 objAlternativeNames.Add(objDirectoryName); 
 objExtensionAlternativeNames.InitializeEncode(objAlternativeNames); 
 objPkcs10.X509Extensions.Add((CX509Extension)objExtensionAlternativeNames); 
 

I hope this helps.

Regards,

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2011/11/07/how-to-add-subject-alternative-name-to-your-certificate-requests-c/
Post name: How to add Subject Alternative Name to your certificate requests (C#)
Original author: Alejandro Campos Magencio
Posting date: 2011-11-07T06:41:06+00:00


Hi all,

The other day a customer of mine wanted to add Subject Alternative Name (szOID_SUBJECT_ALT_NAME2 - "2.5.29.17") extension to his certificate requests in C# and he didn't know how.

We have IX509ExtensionAlternativeNames interface for that, and a C++ sample can be found here:

enrollCustomPKCS10
"
When you install the Microsoft Windows Software Development Kit (SDK), the sample is installed, by default, in the %ProgramFiles%\Microsoft SDKs\Windows\v7.0\Samples\Security\X509 Certificate Enrollment\VC\enrollCustomPKCS10 folder.
...
5.Creates an IAlternativeName object, initializes it by using the RFC822 name specified on the command line, Creates an IAlternativeNames collection, adds the new IAlternativeName (RFC822 name ) object to the collection, creates an IX509ExtensionAlternativeNames object and adds this object to the request.
"

This sample is available in the latest Microsoft SDK 7.1 too.

The C# code to set this extension should look something like this (taking a sample like this as a base: How to create a certificate request with CertEnroll and .NET (C#)):

 string strRfc822Name = "My Alternative RFC822 Name"; 
 ... 
 CAlternativeName objRfc822Name = new CAlternativeName(); 
 CAlternativeNames objAlternativeNames = new CAlternativeNames(); 
 CX509ExtensionAlternativeNames objExtensionAlternativeNames = new CX509ExtensionAlternativeNames(); 
 ... 
 
 // Set Alternative RFC822 Name 
 objRfc822Name.InitializeFromString(AlternativeNameType.XCN_CERT_ALT_NAME_RFC822_NAME, strRfc822Name); 
 
 // Set Alternative Names
 objAlternativeNames.Add(objRfc822Name);
 objExtensionAlternativeNames.InitializeEncode(objAlternativeNames);
 objPkcs10.X509Extensions.Add((CX509Extension)objExtensionAlternativeNames);

I hope this helps.

Regards,

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2011/11/07/how-to-request-a-certificate-programmatically-using-the-certificate-enrollment-web-services-c/
Post name: How to request a certificate programmatically using the Certificate Enrollment Web Services (C#)
Original author: Alejandro Campos Magencio
Posting date: 2011-11-07T06:13:00+00:00


Hi all,

Some time ago I mentioned a Microsoft SDK sample that uses CertEnroll to access the Certificate Enrollment Web Services and enroll a certificate using a template:

How to access the new Certificate Enrollment Web Services programmatically

Now, if you see that sample, it just selects a certificatetemplate and enrolls the certificate with it, but it doesn't customize the request in any way. And a customer of mine wanted to enroll a certificate with specific properties and extensions like Subject, Key Usage, Key Size and Enhanced Key Usage, in the same way we do it in the following samples:

How to request an smartcard logon cert programmatically (C#)

How to create a certificate request with CertEnroll and .NET (C#)

So up to this point we have two different codes: one from Microsoft SDK which makes an enrollmentrequests to the web services, and one which successfully makes custom certificate requests with all the properties and extensions we need to any Certificate Authority. How do we put them together?

The IX509Enrollment2 interface has a Request property of type IX509CertificateRequest that we can use here. We will have to get the Request object first and call the methods we need on it to add all the required info to the cert request, and then call Enroll. The piece of code that puts everything together would look like this:

 // Initialize the request from the template 
 objEnroll.InitializeFromTemplate(...) 
 
 // Customize the request 
 objPkcs10 = objEnroll.Request.GetInnerRequest(InnerRequestLevel.LevelInnermost) as CX509CertificateRequestPkcs10; 
 .... 
 objPkcs10.Subject = objDN; 
 ... 
 // Enroll the certificate 
 objEnroll.Enroll();

I hope this helps.

Regards,

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2011/09/27/how-to-customize-error-messages-shown-when-changing-password-on-windows-7/
Post name: How to customize error messages shown when changing password on Windows 7
Original author: Alejandro Campos Magencio
Posting date: 2011-09-27T05:27:21+00:00


Hi all,

A customer of mine wanted to change the error messages shown to users when changing their password on Windows 7, e.g. when new and old passwords won't match, or the old password of the user is invalid, etc. On Windows XP they did that with a custom Gina. They wondered if they could do this with Credential Providers now.

And the answe is yes. We may wrap the MS Password Credential Provider. When we fail to change the password, authui!CPasswordCredential::ReportResult returns the error in its ppwszOptionalStatusText out parameter (e.g. "The user name or password is incorrect." in my tests). We should be able to modify that string easily in the credential provider wrapper.

The following Microsoft SDK sample shows how to wrap a provider:

Microsoft SDKs\Windows\v7.1\Samples\security\credentialproviders\samplewrapexistingcredentialprovider

I hope this helps.

Regards,

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2011/09/27/faxsenddocument-api-does-not-return-when-called-from-a-windows-service/
Post name: FaxSendDocument API does not return when called from a Windows service
Original author: Alejandro Campos Magencio
Posting date: 2011-09-27T03:26:30+00:00


Hi all,

Some time ago a customer of mine was developing a native application using Fax API, which worked fine on Windows Server 2003. On Windows Server 2008 though, when the application was being run as a service, they could see that FaxSendDocument API was not returning. But everything worked fine on that OS when a user run the application manually.

The RTF document they were sending was very simple and it didn't contain links, so they were not in this situation:

FaxSendDocument function

When you send a document from an application, links in the document may cause a dialog to appear, requesting information. If you do not handle the information request within several minutes, FaxSendDocument will fail and return an error.


The fax service only understands TIFF files naturally. So when you fax any other file format, it must first convert it to TIFF. Since the Fax Service doesn't know (for example) RTF, it leverages installed applications to do the rendering for it. The way it does this is by calling ShellExecute APIon the document with the "printto" verb and the fax printer as the destination. The output of the fax printer is a TIFF file that the fax service can then fax.

About Sending a Fax
"
Printing from an application to the fax printer
In this process, the fax is sent from within the application. The printing application directly renders the image to be printed (faxed) and no further conversion is required.

The fax printer driver saves the rendered image as a temporary Tagged Image File Format (TIFF) file and sends it to the fax service for queuing and transmission. The fax send wizard is displayed so the user can provide specific fax transmission data.
"

In my customer's case, they were using MS Word 2010 to render the TIFF file, and Word is not supported in a service scenario: Considerations for server-side Automation of Office.

The only supported solutions I found that may work (note I didn't try them myself) are:

1)Change the application associated to RTF files.
2)Convert RTF files to TIFF in some other way (e.g. using third-party libraries or tools instead of Word), and then fax the TIFF file directly.

In the end, enabling the "Allow service to interact with desktop" flag on the service made FaxSendDocument API to stop hanging.

I hope this helps.

Regards,

Alex (Alejandro Campos Magencio)