GnuPG 2.2.8 compatibility for .NET

As of version 2.2.8, GnuPG/gpg will not accept encrypted or signed and encrypted .pgp files which don’t have integrity protection packet, also known as Modification detection code (MDC packet). This will be the default behavior of GnuPG from now on, and is their answer to the EFAIL attack.

Our product OpenPGP Library for .NET exposes methods which allow explicit setting of the integrity protection packet. But up till now the methods where this parameter was absent didn’t used integrity protection and the output from them will not be accepted by all new versions of GnuPG. This applies also to all methods that deal with output as String type.

In order to address this issue, version 1.8.4 of DidiSoft OpenPGP Library for .NET  exposes a new property of the PGPLib class : PGPLib.IntegrityProtectArchives. Sample usage is :

PGPLib pgp = new PGPLib();
pgp.IntegrityProtectArchives = true;

This code block will ensure that all subsequent operations where Integrity protection is not specified explicitly will use it and the output will be accepted from GnuPG 2.2.8 and upper versions. The same applies to Symantec PGP Command Line 10.4.2 and newer versions.

Read more...

Compatibility with Java 7+ RSA signatures

As of Java version 7 and above the RSA digital signatures computation has been changed and signatures that were previously accepted by software build with Java may end being rejected with message like: “unable to verify signature: Signature length not correct: got 511 but was expecting 512

Solutions using DidiSoft OpenPGP Library for .NET may be affected when they send signed or signed and encrypted PGP data with software systems build in Java. A recent example we had was with TIBCO MFT, throwing the above mentioned error.

The technical explanation of the problem is that a digital signature consists of MPI (multi precision integers) which are kept in array of bits (not bytes!) and when serialized they may end being less then a number power of two.

Version 1.8.3.5 of OpenPGP Library for .NET resolves this issue by padding with leading zero bytes up to a length power of two. If you encounter such behavior then please upgrade.

Read more...

Should the EFAIL attack concern your PGP applications

A few days ago in the world of applied cryptography especially S/MIME and PGP emails has appeared a new threat – the EFAIL attack.

In this post we are not going to explain again details of the attack itself as a lot has already been published on the Internet, but rather explain do you have to be concerned using any of the DidiSoft OpenPGP products.

The EFAIL attack in breaf

The EFAIL attack in short consists of allowing the receiver to decrypt the data and send it via HTTP request to the intruder. In the examples published in the source article this is done with an image tag artificial inserted by the intruder and the decrypted data sent as an HTTP request parameter for the image tag location (assumed to be on the intruder’s web host).

The main target of the attack is S/MIME and PGP encrypted email messages.

First approach (image tag)

The first approach they use is by modifying the email and introducing a new body part before the encrypted email body part, which contains an unclosed image tag.

Our proposed Solution

When implementing email rendering do not allow unclosed tags in a MIME section and perform HTML purification independently for each MIME body part.

Second approach (CBC/CFB gadget)

The second technique, named CBC/CFB gadget attack, exploits vulnerabilities in OpenPGP (CVE-2017-17688) and S/MIME (CVE-2017-17689).

From the EFAIL article the reader may conclude that the second vulnerability is something that a 12 year old boy can do at home:

“Given the current state of our research, the CFB gadget attack against PGP only has a success rate of approximately one in three attempts”

The reality tends to be different though. This is still an unconfirmed threat to PGP/MIME emails. The current Security Focus state regarding exploits is “Currently, we are not aware of any working exploits“. PGP/MIME emails with Integrity protection packet cannot be modified as of the time of this writing.

Our proposed Solution

When receiving PGP/MIME emails DidiSoft products will rise exception whether or not integrity protection has been set on the incoming data.

When sending PGP/MIME emails to other entities using DidiSoft products, please ensure that integrity check has been turned on!

Conclusion

The EFAIL attack exploits weaknesses in the implementation of some PGP email clients. The mass press coverage raised uncertainty in organizations relying on PGP encryption, but the attack targets PGP email client implementations and not PGP encryption as a whole.

We also recommend  you to read the one page official answer from the core PGP developers.

Read more...

Should DidiSoft OpenPGP Library for .NET provide strong name assemblies or unsigned assemblies?

Last week we have sent a short survey to subscribers for our OpenPGP Library for .NET mailing list. The survey had only one question:

Should DidiSoft OpenPGP Library for .NET provide strong name (signed) assemblies (DLL’s) or plain unsigned assemblies?

At the end of this post you will find the results of the survey, but first lets explain why did we made it.

DidiSoft OpenPGP Library for .NET was providing limited PGP emails support due to limitations in the System.Net.Mail namespace implementation regarding the MIME email formats (in fact we supported only PGP-inline emails). Recently we had received a numerous requests for additional support for PGP/MIME email format. In order to implement it we decided to use the open source MimeKit library but this is the moment where we were hit with this case:

+-------+        +---+         +--------+
|   B   +------->+ A +<--------+    D   |
+---+---+        +---+         +--------+
^                               ^
|                               |
|                               |
+---+---+                       +---+---+
|  C.1  |                       |  C.2  |
+-------+                       +-------+

Assembly A needs to use assemblies B and D, which reference different versions of assembly C. Of course this can be resolved with binding redirect in the app.config or dynamically in the AppDomain.CurrentDomain.AssemblyResolve event. But our aim was to provide a DidiSoft.Pgp.Mail.dll which use will be as simple as just referencing it straight away.

Digging for more information in Stackoverflow and MSDN we found out that probably the days when strong named assemblies were a must may have passed away. In order to hear what our community thinks we decided to file the survey. And here are the results:

The results are self explanatory – we must provide both strong named DLLs and unsigned too.

 

Read more...

OpenPGP Library for .NET 1.7.14 with Web of Trust

DidiSoft OpenPGP Library for .NET 1.7.14 was released today offering extended support for OpenPGP Web of Trust.

In previous versions of the library only setting own trust was available and plain signing of keys.

With this new release keys status can be checked by Trust amount and Verified status. We can also sign public keys with plain and trust signatures, with the option for specifying trust depth.

Check the online Tutorial for Web of Trust in order to learn this new functionality.

Upgrade notes

With this version of the library newly generated keys have Trust value of Ultimate automatically. Unfortunately if we have key pairs generated with previous versions of the library, they have Trust value Unknown. We can upgrade them with a one time execution of the code below:

C#

// ks1 is of type DidiSoft.Pgp.KeyStore
foreach (KeyPairInformation k in ks1.GetKeys())
{
      if (key.HasPrivateKey)
      {
            ks1.SetTrust(k.KeyIdHex, TrustLevel.Ultimate);
      }
}

VB.NET

' ks1 is of type DidiSoft.Pgp.KeyStore
For Each k As KeyPairInformation In ks1.GetKeys()
  If key.HasPrivateKey Then
    ks1.SetTrust(k.KeyIdHex, TrustLevel.Ultimate)
  End If
Next

 

Read more...

OpenPGP Library for .NET in Mono

DidiSoft OpenPGP Library for .NET can be used without any problems in Mono projects under Mac OSX and Linux.

The library DLL files that you have to reference in your Mono project are the ones located in the root of the \Bin folder.

A limitation for Mono developers is that they have to first install the library setup on a Windows machine in order to get the DLL files and then copy them on their Mac OSX or Linux development station.

 

Read more...

Using a public key by mistake when decrypting

A common scenario that we have evidenced in our technical support practice for DidiSoft OpenPGP Library for .NET is that some customers by mistake try to decrypt .pgp files with an OpenPGP public key.

Although the exception was of class DidiSoft.Pgp.Exceptions.WrongPrivateKeyException,  the exception text so far wasn’t very helpful and it stated: “Decryption of data encrypted using KEY-ID(s) : XXX failed, The provided key is not a valid OpenPGP private key.”.

As of version 1.7.11.11 the library was updated to check if the supplied key is a public key and in that case the exception will be “Decryption of data encrypted using KEY-ID(s) : XXX failed, The provided key is a Public Key (You need a Private Key for decryption!)

Read more...

Invoking OpenPGP Library for .NET from MS SQL Server

In this article we are going to illustrate how to invoke DidiSoft OpenPGP Library for .NET from MS SQL Server (tm) stored procedures and T-SQL code.

We also provide a dedicated set of Transact-SQL routines in the product MsSqlPGP.

Note: This information applies to MS SQL Server 2005 and above. All the demonstrated code below should be executed from SQL Server Management Studio ™ or similar environment, if not specified otherwise.

Table of Contents

Database configuration

In order to allow execution of .NET CLR code in a database, a special setting has to be activated for it:

1
2
3
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;

The database must allow unsafe code:

1
ALTER DATABASE MyDatabase SET TRUSTWORTHY ON;

Assembly registration

The next step is to register the DLL files of the library:

1
2
3
4
5
6
7
CREATE ASSEMBLY [BouncyCastle.CryptoExt]
FROM 'C:\Program Files (x86)\OpenPGP Library for .NET 1.7.10\Bin\BouncyCastle.CryptoExt.dll'
WITH PERMISSION_SET = UNSAFE;
 
CREATE ASSEMBLY [DidiSoft.Pgp]
FROM 'C:\Program Files (x86)\OpenPGP Library for .NET 1.7.10\Bin\DidiSoft.Pgp.dll'
WITH PERMISSION_SET = UNSAFE;

Wrapping the OpenPGP functionality in Stored procedures

In order to use the functionality provided by the library, we have to create wrappers as managed Stored procedures. Below is an example that exposes the basic encryption and decryption methods offered by the library:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
 
using DidiSoft.Pgp;
 
namespace MyStoredProcedures
{
    public partial class MsSqlPgp
    {
        [SqlProcedure()]
        public static void EncryptFile(SqlString data, SqlString publicKey, SqlString outFile)
        {
            PGPLib pgp = new PGPLib();
            pgp.EncryptFile(data.Value, publicKey.Value, outFile.Value);
        }
 
        [SqlProcedure()]
        public static void DecryptFile(SqlString data, 
                                       SqlString privateKey, 
                                       SqlString keyPassword, 
                                       SqlString outFile)
        {
            PGPLib pgp = new PGPLib();
            pgp.DecryptFile(data.Value, privateKey.Value, keyPassword.Value, outFile.Value);
        }
    }
}

Of course, the assembly where the above code resides must also be registered in the same database. Let’s assume that it is registered with the alias MyStoredProcedures. Each of its methods must be registered as a stored procedure:

1
2
3
4
5
6
7
8
9
10
11
12
CREATE PROCEDURE usp_PgpEncryptFile
@dataFile nvarchar(MAX),
@publicKey nvarchar(MAX),
@OUTFILE nvarchar(MAX)
AS EXTERNAL NAME [MyStoredProcedures].[MyStoredProcedures].EncryptFile;
 
CREATE PROCEDURE usp_PgpDecryptFile
@pgpFile nvarchar(MAX),
@privateKey nvarchar(MAX),
@keyPassword nvarchar(MAX),
@OUTFILE nvarchar(MAX)
AS EXTERNAL NAME [MyStoredProcedures].[MyStoredProcedures.MsSqlPgp].DecryptFile;

Invoking the wrapped Stored procedures

The invocation of the wrapped code is no different than any other stored procedure call:

1
2
3
EXEC usp_PgpEncryptFile 'c:\Test\mydata.txt', 'c:\Test\public.asc', 'c:\Test\output.pgp';
 
EXEC usp_PgpDecryptFile 'c:\Test\input.pgp', 'c:\Test\private.asc', 'my password', 'c:\Test\output.txt';

Upgrading the library

In order to upgrade the library to a newer version we have to first DROP any linked stored procedure, and afterwards DROP the assemblies, but in reverse order:

1
2
DROP ASSEMBLY [DidiSoft.Pgp];
DROP ASSEMBLY [BouncyCastle.CryptoExt];

After that we shall proceed as the normal setup.

Summary

This chapter illustrated how to invoke functionality from DidiSoft OpenPGP Library for .NET in MS SQL Server ™ hosted environment.

If you need a complete solution with Transact-SQL OpenPGP cryptography, check our dedicated product MsSqlPGP.

Read more...

premature end of stream in PartialInputStream

The latest release of DidiSoft OpenPGP Library for .NET (1.7.9.14) and OpenPGP Library for Java (2.6.6.3) ship with bug fix for the error “premature end of stream in PartialInputStream“.

The error “premature end of stream in PartialInputStream” may be observed when trying to decrypt .pgp data with wrong internal length indicators , usually when the encrypted content is text data. Example of such data can be found at http://bouncy-castle.1462172.n4.nabble.com/potential-bug-premature-end-of-stream-exception-in-pgp-message-td4302017.html

In order to avoid this error, please make sure that you are using the latest version of the libraries.

The DidiSoft Team.

Read more...

Using OpenPGP for .NET from Windows PowerShell

As of version 1.7.15 we provide a PowerShell ready module installed and imported in Windows PowerShell with the library. A complete tutorial chapter is available here.

 

(Obsolete: see www.didisoft.com/net-openpgp/examples/powershell/)
This article contains basic information regarding using DidiSoft OpenPGP Library for .NET from Windows PowerShell.

1. Referencing the library

In order to access the classes exposed by the library in PowerShell we need to introduce them to the PowerShell environment. This is achieved with the Add-Type -Path command.

PS C:\Users\Me> Add-Type -Path 'C:\Program Files (x86)\OpenPGP Library for .NET 1.7.7\Bin\BouncyCastle.CryptoExt.dll'
PS C:\Users\Me> Add-Type -Path 'C:\Program Files (x86)\OpenPGP Library for .NET 1.7.7\Bin\DidiSoft.Pgp.dll'

2. Invoking methods

The method invocation is analogous to the invocation of the built-in .NET classes. Below is an example that shows how to OpenPGP encrypt a string message. Of course the library must have been referenced previously.

PS C:\Users\Me> $pgp = New-Object DidiSoft.Pgp.PGPLib
PS C:\Users\Me> $pgp.EncryptString("Hello World", "c:\OpenPGPKeys\public_key.asc")

The result from the above commands will be the encrypted string in ASCII armored format.

Summary

This chapter is just an introduction how to use DidiSoft OpenPGP Library for .NET in Windows PowerShell.

You may also be interested in examining the PowerShell module provided by the library.

Read more...