Posts on this page:

SSL key exchange with and without encryption

Recently, a friend of mine asked a question about key exchange in SSL without encrypting the key. His question came after examining a Key Usage certificate extension setting in the certificate template. There are two options: Allow key exchange only with key encryption and Allow key exchange without key encryption. How it can be possible that the key is not encrypted??? Here is an image of the respective setting:

Key Usage extension configuration in certificate template


read more →

Test web server SSL/TLS protocol support with PowerShell

Recently I was tasked to configure SSL/TLS protocols and cipher suites for internal web servers via Group Policy. At first, we collected a list of web server and web client applications to determine the weakest possible SSL/TLS protocols. Once the list was complete, we deployed sample policy in test OU and finally applied them to the rest domain.

Now I was tasked to scan web servers to determine if they match new security policy. In order to minimize my effort in testing, I wrote a simple PowerShell script that accepts a list of web URLs and tests each host with a list of SSL protocols: SSLv2, SSLv3, TLS 1.0, TLS 1.1 and TLS 1.2. Here is a sample code:


read more →

Welcome to my new web home!

welcome

Finally I did it! I burned my old SharePoint blog and R.I.P.?ed my former Russian blog (DasBlog) as promised.

The problem

Just to recall the history. Several years ago I realized that I need a new website/portal to host my stuff. Initially I looked for a ready solution that would match my humble requirements:

  1. It should support hierarchical site directories to organize content;
  2. It should support SQL database;
  3. It should support multi-level hierarchical content categories;
  4. It should support an ability to control rendering;
  5. It should support old URLs and redirect to migrated cont...

read more →

Certificate Rules may not work in Software Restriction Policies

SYMPTOMS

Consider the following scenario. You configured Software Restriction Policies (SRP) to allow run all applications that are signed by the specific signer by creating a Certificate Rule against the signer certificate.

When the policy is refreshed on the client, user cannot run the application, because it is blocked by Software Restriction Policies.

 

CAUSE

This behavior occurs when the certificate is issued by a Certification Authority (CA) which do not include or provide incorrect issuer information in the Authority Information Access (AIA) extension in the signing certificate. In addition, intermediate CA certificate is not installed in the local store. SRP reads only signing certificate in the digital signature and ignores the rest certificates.

This issue may occur when the signing certificate was issued by Thawte due to their CA certificate distribution policy.

STATUS

This behavior is by design. No bug fixes are available. See Workaround section for example steps to overcome the issue.

WORKAROUND

Perform the following steps to install intermediate CA certificate to local certificate store.

Option 1 is a general guidance for intermediate CA certificate retrieval. Option 2 is used only for signing certificates issued by Thawte.

Option 1

Option 2

The following steps can be used to save Thawte Code Signing CA – G2 certificate to a file:

  1. Run Notepad;
  2. Copy the following text and paste it to Notepad:

    -----BEGIN CERTIFICATE-----
    MIIEnDCCA4SgAwIBAgIQR5dNeHOlvKsNL7NwGS/OXjANBgkqhkiG9w0BAQUFADCB
    qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
    Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
    MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
    BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTAwMjA4MDAwMDAwWhcNMjAw
    MjA3MjM1OTU5WjBKMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMVGhhd3RlLCBJbmMu
    MSQwIgYDVQQDExtUaGF3dGUgQ29kZSBTaWduaW5nIENBIC0gRzIwggEiMA0GCSqG
    SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3i891W58l2n45sJPbONOpI9CC+ukkflwL
    joP45npZ5qPFmKeZ0kT/AKalOQSK2imI6tui8xyZFSbCsfT84QxHqQkRBgogkrnH
    oASMXJQZq1slLB1ifnANzmFs3SuCyc5dSF/3wr68QSMeTyld10+89MUq/GPmfCZO
    mad5QZ4QSnp5ycaG94aV0ibOPBgq1nzOr82tu/eCLHAmN0XlD0cixgEovS6DXGqk
    R8Hn0NhrgUY/IRf1B8VDWqZnLLh7YBG1g+71dApycUQ9WP7oGqs4w1nbf244fXbH
    cmmYNpZX02Yc0lSRBC5UGbDcPbUiXobVKn4g313merFl/sUCTjEtAgMBAAGjggEc
    MIIBGDASBgNVHRMBAf8ECDAGAQH/AgEAMDQGA1UdHwQtMCswKaAnoCWGI2h0dHA6
    Ly9jcmwudGhhd3RlLmNvbS9UaGF3dGVQQ0EuY3JsMA4GA1UdDwEB/wQEAwIBBjAy
    BggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnRoYXd0ZS5j
    b20wHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMDMCkGA1UdEQQiMCCkHjAc
    MRowGAYDVQQDExFWZXJpU2lnbk1QS0ktMi0xMDAdBgNVHQ4EFgQU1A1lP3q9NMb+
    R+dMDcC98t4Vq3EwHwYDVR0jBBgwFoAUe1tFz6/Oy3r9MZIaarbzRutXSFAwDQYJ
    KoZIhvcNAQEFBQADggEBAFb+U1zhx568p+1+U21qFEtRjEBegF+qpOgv7zjIBMnK
    Ps/fOlhOsNS2Y8UpV/oCBZpFTWjbKhvUND2fAMNay5VJpW7hsMX8QU1BSm/Td8jX
    OI3kGd4Y8x8VZYNtRQxT+QqaLqVdv28ygRiSGWpVAK1jHFIGflXZKWiuSnwYmnmI
    ayMj2Cc4KimHdsr7x7ZiIx/telZM3ZwyW/U9DEYYlTsqI2iDZEHZAG0PGSQVaHK9
    xXFnbqxM25DrUaUaYgfQvmoARzxyL+xPYT5zhc5aCre6wBwTdeMiOSjdbR0JRp1P
    uuhAgZHGpM6UchsBzypuFWeVia59t7fN+Qo9dbZrPCU=
    -----END CERTIFICATE-----

  3. Click File menu and click Save or Save As...;
  4. In the Save dialog, select the path and file name. Append “.cer” extension to the end of the file name;
  5. In the Save as type drop-down list, select All Files (*.*);
  6. Make sure that Encoding drop-down list is set to ANSI:
    image
  7. Click Save button to save the file.

CA certificate installation instructions:

There are three options to install CA certificate to local certificate store:

  • Option 1 installs CA certificate to local machine only;
  • Option 2 installs CA certificate to a set of computers depending on Group Policy object scope in Active Directory;
  • Option 3 installs CA certificate to all machines in the current Active Directory forest

Option 1

  1. Log on to target computer with local Administrator permissions;
  2. Run Command Prompt in elevated mode;
  3. In the Command Prompt, type the following command:

    certutil -f –addstore CA path\cacertfile.cer

    change “path\cacert.cer” part with actual path and file name.
  4. Close Command Prompt.

Option 2

  1. Log on to a computer where Group Policy management tools are installed with Domain Admins permissions;
  2. Run Group Policy Management console (gpmc.msc);
  3. Edit existing or create a new Group Policy Object (GPO).
  4. In the GPO editor, expand Computer Configuration\Policies\Windows Settings\Security Settings\Public Key Infrastructure.
  5. Under Public Key Infrastructure node right-click on Intermediate Certification Authorities and click Import;
  6. Follow Certificate Import Wizard instructions to import CA certificate;
  7. Close GPO editor and Group Policy Management console.

When completed, refresh the group policy on the target clients by running “gpupdate /force” command.

Option 3

  1. Log on to any Active Directory member with Enterprise Administrator permissions;
  2. Run Command Prompt in elevated mode;
  3. In the Command Prompt, type the following command:

    certutil –dspublish –f path\cacertfile.cer SubCA

    change “path\cacert.cer” part with actual path and file name.
  4. Close command Prompt.

When completed, refresh the group policy on the target clients by running “gpupdate /force” command.

    Note: Option 3 requires that Autoenrollment policy is enabled on clients.


    APPLIES TO
    • Windows XP Professional
    • Windows Server 2003 (all editions)
    • Windows Vista Business, Ultimate, Enterprise
    • Windows Server 2008 (all editions)
    • Windows 7 Professional, Ultimate, Enterprise
    • Windows Server 2008 R2 (all editions)
    • Windows 8 Professional, Enterprise
    • Windows Server 2012 (all editions)
    • Windows 8.1 Professional, Enterprise
    • Windows Server 2012 R2 (all editions)

    Test PFX (PKCS#12) file and PFX password with CryptoAPI in PowerShell

    Today I want to present another useful CryptoAPI functions to use when working with PFX (PKCS#12) certificates.

    1. Determine if the BLOB is PFX without having to pass a password;
    2. Test PFX password.

    Of course, you can try to use appropriate X509Certificate2 class constructor, but this approach is faster and do not require key import in cryptographic provider and other actions performed by X509Certificate2 constructor. This functionality is implemented in two CryptoAPI functions:

    1. PFXIsPFXBlob
    2. PFXVerifyPassword

    And here is complete solution:

    $signature = @"
    [DllImport("Crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool PFXIsPFXBlob(
        CRYPTOAPI_BLOB pPFX
    );
    [DllImport("Crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool PFXVerifyPassword(
        CRYPTOAPI_BLOB pPFX,
        [MarshalAs(UnmanagedType.LPWStr)]
        string szPassword,
        int dwFlags
    );
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct CRYPTOAPI_BLOB {
        public int cbData;
        public IntPtr pbData;
    }
    "@
    Add-Type -MemberDefinition $signature -Namespace PKI -Name Crypt32
    
    function Test-CertIsPfx ([Byte[]]$RawData) {
        # create buffer in an unmanaged memory to store raw data
        $pbData = [Runtime.InteropServices.Marshal]::AllocHGlobal($RawData.Length)
        # copy bytes to unmanaged buffer:
        [Runtime.InteropServices.Marshal]::Copy($RawData,0,$pbData,$RawData.Length)
        # create CRYPTOAPI_BLOB structure
        $blob = New-Object PKI.Crypt32+CRYPTOAPI_BLOB -Property @{
            cbData = $RawData.Length
            pbData = $pbData
        }
        # call the PFXVerifyPassword to test the content. The function returns $true
        # if byte array represents PFX file.
        [PKI.Crypt32]::PFXIsPFXBlob($blob)
        # release unmanaged buffer:
        [Runtime.InteropServices.Marshal]::FreeHGlobal($pbData)
    }
    function Test-PfxPassword ([Byte[]]$RawData, [string]$Password) {
        # create buffer in an unmanaged memory to store raw data
        $pbData = [Runtime.InteropServices.Marshal]::AllocHGlobal($RawData.Length)
        # copy bytes to unmanaged buffer:
        [Runtime.InteropServices.Marshal]::Copy($RawData,0,$pbData,$RawData.Length)
        # create CRYPTOAPI_BLOB structure
        $blob = New-Object PKI.Crypt32+CRYPTOAPI_BLOB -Property @{
            cbData = $RawData.Length
            pbData = $pbData
        }
        # call the PFXVerifyPassword to test the password. The function returns $true
        # if password is correct
        [PKI.Crypt32]::PFXVerifyPassword($blob, $Password, 0)
        # release unmanaged buffer:
        [Runtime.InteropServices.Marshal]::FreeHGlobal($pbData)
    }

    and usage:

    [↓] [vPodans] $bytes = [io.file]::ReadAllBytes(".\3.pfx")
    [↓] [vPodans] $bytes2 = [io.file]::ReadAllBytes(".\pem.txt")
    [↓] [vPodans] Test-CertIsPfx $bytes
    True
    [↓] [vPodans] Test-CertIsPfx $bytes2
    False
    [↓] [vPodans] Test-PfxPassword $bytes "1"
    True
    [↓] [vPodans] Test-PfxPassword $bytes "other password"
    False
    [↓] [vPodans]

    Note: PFX files must be stored in a pure binary format. Unlike regular certificates, PFX do not support base64 encoding in files.

    In these examples, I read two files, one PFX, another – “whateverelse” and passed them to Test-CertIsPfx function. As you see, only bytes from “3.pfx” file returned $true. And attempted to guess the password and guessed from the first attempt!!! (joke). This is something you can write during morning coffee/tea :)