Friday, July 21, 2017

SSH-Auth-Caret - Use SSH Agent Socket from remote host

Let's say you have two systems that can connect to the same server. Client1 contains a private key and it's SSH agent is forwarded to the server. Now you want to use a private key in that agent on Client2. There are ofcourse some security concerns when using SSH Agent Forwarding, so please do a proper security assessment before using any of this information.

       | SSH Server |
         /a.       \b.
 -----------      ----------      -------------
|  Client 1 |    | Client 2 | c. | Auth.Server |
| |=        |    |          |----| (eg Github) |
| | prv.key |    | ssh/git/ |     -------------
| O         |    | other    |
 -----------      ----------

a. Setup an SSH connection from Client1 to the server, with SSH Agent Forwarding.

On to the server find the socket you want to use. Assuming the sockets are in /tmp/ssh-* and named agent.*, you can use:

server> for SOCK in /tmp/ssh-*/agent*; do export SSH_AUTH_SOCK=$SOCK; echo $SSH_AUTH_SOCK; ssh-add -l; echo; done

b. Copy or note the path of the socket that has the key you'd like to use. Then connect to the server, from client2, and specify a socket forward:

client2> ssh -o StreamLocalBindUnlink=yes -L/tmp/agent-server:/tmp/ssh-S0ck3t/agent.12345 server.example

The StreamLocalBindUnlink=yes allows ssh to remove the local socket (/tmp/agent-server) if it already exists.

/tmp/agent-server is the name of the local socket, you can choose this freely.

/tmp/ssh-S0ck3t/agent.12345 is the copied or noted path of the socket on the server.

c. Keep the SSH connection to the server open. In another terminal you can now use the socket by specifying it in SSH_AUTH_SOCKET:

client2> export SSH_AUTH_SOCK=/tmp/agent-server
client2> ssh-add -l

I've made a script to help finding and selecting the right socket. You can find it on GitHub:

Saturday, December 19, 2015

TPM authentication in OpenVPN and PuTTY SSH

With my new laptop I wanted to ensure my private keys would be safe. This is a brief summary of the steps I've taken to use a private key in my laptop's TPM to authenticate with OpenVPN and SSH.

Create a virtual smart card

Ensure the TPM is activated.

Start a Command Prompt as admin.
Create a Virtual Smart Card [1].
tpmvscmgr.exe create /name "[hostname] VSC" /pin prompt /adminkey random /generate

Enter PIN:
Confirm PIN:
Creating TPM Smart Card...
Initializing the Virtual Smart Card component...
Creating the Virtual Smart Card component...
Initializing the Virtual Smart Card Simulator...
Creating the Virtual Smart Card Simulator...
Initializing the Virtual Smart Card Reader...
Creating the Virtual Smart Card Reader...
Waiting for TPM Smart Card Device...
Authenticating to the TPM Smart Card...
Generating filesystem on the TPM Smart Card...
TPM Smart Card created.
Smart Card Reader Device Instance ID = ROOT\SMARTCARDREADER\0000

Generate a signing request and have the request signed to obtain a certificate.

Create a request template in Notepad and save this as TPM-cert-template.inf [2].
Subject = "CN=[hostname],O=[Organisation],L=[Location],ST=[State],C=[Country]"
Keylength = 2048
Exportable = FALSE
UserProtected = TRUE
MachineKeySet = FALSE
ProviderName = "Microsoft Base Smart Card Crypto Provider"
ProviderType = 1
RequestType = PKCS10
KeyUsage = 0x80

Then generate a Certificate Request (CSR):
certreq -new -f TPM-cert-template.inf TPM-cert.csr

Send the CSR to your CA and have it signed. You should get a certificate in return.

Install the certificate

Double click the received certificate file (most likely .crt or .cer).
Click on the "Install certificate" button and follow the wizard.

When it's done, obtain the fingerprint of the certificate from the Details tab.

Configure OpenVPN to use the cryptoapi and certificate

Edit the OpenVPN profile.
Instead of a "cert" and "key" configure "cryptoapicert" with your fingerprint:
cryptoapicert "THUMB:92 50 9d ea 52 f4 95 ee be a1 c0 4f ab f8 a2 2b 4d 91 0c 0a"

Save the profile and connect.

Enable SSH authentication with the Virtual SmartCard

Download and install puttywincrypt [3].
Configure putty to use the certificate under Connection -> SSH -> Auth by entering [4]:

Update: WinSCP

WinSCP turned out to work with the certificate through pageant when using "SCP" as protocol and checking the checkbox in SSH, Authentication "Attempt authentication using Pageant".

Update: Listing
wmic path win32_PnPEntity where "DeviceID like '%smartcardreader%'" get Caption,DeviceID

Update: Dell XPS 13
After updating my XPS 13's TPM firware to 2.0 I was no longer able to use the TPM certificate for authentication. Trying to revert back to firmware 1.2 that showed to be working failed with an error "Invalid source version". Contacting Dell did not help. They answerd my mails with requests for support with links to online contact that I had already found or was irrelevant and finally let me know "TPM is not supported by [Dell]. If the problem is not solved I advise you to contact Intel." Thanks to post I've found on Reddit [5] I was finally able to revert back to version 1.2 and issue a new certificate.

Sources used

Thursday, April 25, 2013

WiFi QR-code generator

Usage preview

With current (Android) mobiles it is possible to add a WiFi network by scanning a QR-code. Barcode Scanner by ZXing Team is one of the apps recognizing the WiFi QR-codes. Other QR-code generators online (that support WiFi-QR) generate the QR-code server side, which means the data, including the password, is sent over the internet. Since I wasn't comfortable with this, I have created an open source Javascript alternative.

Use this generator to generate a QR-code without having your precious WiFi information sent over the internet. Such a QR-code might, for example, be useful to allow your guests to easily add your WiFi network to their phone when visiting.

Select the encryption used in your network (WEP, WPA or none).
Enter your SSID.
Enter the password for the network.
If the SSID is hidden, set the visibility button to 'Hidden'.
Click 'Generate' and/or 'Print'

Friday, April 12, 2013

PKCS#7 and OpenSSL

In an earlier post I have tried to demonstrate how to verify a PKCS#7 manually, because I wanted to know how such messages work and why it would be secure. Judging by the reactions that were posted I think a lot  you are actually more interested in a proper way of decrypting and verifying PKCS#7 messages with OpenSSL. Therefore I will show you how to encrypt, decrypt, sign and verify PKCS#7 messages, with OpenSSL in a more proper way.

NOTE: to actually use these methods securely could, and probably does, require decent understanding of data encryption!

If you are in doubt, feel free to leave a message and I'll try to be of assistance.


Before we can start encrypting and signing messages we'll require some keys and certificates. Let's create a self-signed certificate based on a new key with the subject "PKCS#7 example".

openssl req -x509 -nodes -newkey rsa:1024 -keyout keyfile.key -out certificate.cer -subj "/CN=PKCS#7 example"

This should result in the creation of two new files:
  • certificate.cer - containing a PEM-encoded X.509 certificate
  • keyfile.key - containing a PEM-encoded (RSA) private key
To view ASN.1 encoded files, both, DER and PEM, with more ease I have created two aliases in my terminal:

alias oad='openssl asn1parse -inform der -in'
alias oap='openssl asn1parse -inform pem -in'

oad is used to "OpenSSL ASN.1 dump DER"
oap is used to "OpenSSL ASN.1 dump PEM"

oap certificate.cer
    0:d=0  hl=4 l= 512 cons: SEQUENCE
    4:d=1  hl=4 l= 361 cons: SEQUENCE
    8:d=2  hl=2 l=   3 cons: cont [ 0 ]
   10:d=3  hl=2 l=   1 prim: INTEGER           :02
   13:d=2  hl=2 l=   9 prim: INTEGER           :D28124BDCEECCCCC
   24:d=2  hl=2 l=  13 cons: SEQUENCE
   26:d=3  hl=2 l=   9 prim: OBJECT            :sha1WithRSAEncryption
   37:d=3  hl=2 l=   0 prim: NULL
   39:d=2  hl=2 l=  25 cons: SEQUENCE
   41:d=3  hl=2 l=  23 cons: SET
   43:d=4  hl=2 l=  21 cons: SEQUENCE
   45:d=5  hl=2 l=   3 prim: OBJECT            :commonName
   50:d=5  hl=2 l=  14 prim: UTF8STRING        :PKCS#7 example
   66:d=2  hl=2 l=  30 cons: SEQUENCE
   68:d=3  hl=2 l=  13 prim: UTCTIME           :130412203318Z
   83:d=3  hl=2 l=  13 prim: UTCTIME           :130512203318Z
   98:d=2  hl=2 l=  25 cons: SEQUENCE
  100:d=3  hl=2 l=  23 cons: SET
  102:d=4  hl=2 l=  21 cons: SEQUENCE
  104:d=5  hl=2 l=   3 prim: OBJECT            :commonName
  109:d=5  hl=2 l=  14 prim: UTF8STRING        :PKCS#7 example
  125:d=2  hl=3 l= 159 cons: SEQUENCE
  128:d=3  hl=2 l=  13 cons: SEQUENCE
  130:d=4  hl=2 l=   9 prim: OBJECT            :rsaEncryption
  141:d=4  hl=2 l=   0 prim: NULL
  143:d=3  hl=3 l= 141 prim: BIT STRING
  287:d=2  hl=2 l=  80 cons: cont [ 3 ]
  289:d=3  hl=2 l=  78 cons: SEQUENCE
  291:d=4  hl=2 l=  29 cons: SEQUENCE
  293:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Subject Key Identifier
  298:d=5  hl=2 l=  22 prim: OCTET STRING      [HEX DUMP]:0414B2ED2165623A8E3E5EB9652E781590C314EFC5B6
  322:d=4  hl=2 l=  31 cons: SEQUENCE
  324:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Authority Key Identifier
  329:d=5  hl=2 l=  24 prim: OCTET STRING      [HEX DUMP]:30168014B2ED2165623A8E3E5EB9652E781590C314EFC5B6
  355:d=4  hl=2 l=  12 cons: SEQUENCE
  357:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Basic Constraints
  362:d=5  hl=2 l=   5 prim: OCTET STRING      [HEX DUMP]:30030101FF
  369:d=1  hl=2 l=  13 cons: SEQUENCE
  371:d=2  hl=2 l=   9 prim: OBJECT            :sha1WithRSAEncryption
  382:d=2  hl=2 l=   0 prim: NULL
  384:d=1  hl=3 l= 129 prim: BIT STRING


Encryption can be used to make a message only available to the target receiver and prevents eavesdropping. The message is encrypted with a public key, quiet often stored in a certificate. Because of the mathematical properties of the private and public key, the message can only be read with possession of the private key. In this example I'll show you how to encrypt a message that is only readable when decrypted with the private key created before. To encrypt a message we'll be using the newly created certificate we're using the smime command of OpenSSL. Have a look at the help for all the available options of this command (openssl smime --help).

Store the message we'll be encrypting in a file:
echo "This message won't be readable until decrypted again." > plain-original.txt

Then encrypt this message using the key from the certificate.cer created earlier. If the outform isn't specified the default output format is smime, for now I'll use pem:
openssl smime -encrypt -in plain-original.txt -outform pem -out encrypted.p7 certificate.cer

Verifiy the encrypted.p7 contains content that looks a bit like this:
oap encrypted.p7
-----BEGIN PKCS7-----
-----END PKCS7-----


A PKCS#7 encrypted message can be recognized by the PKCS#7 content type, which is pkcs7-envelopedData:
oap encrypted.p7
    0:d=0  hl=4 l= 316 cons: SEQUENCE
    4:d=1  hl=2 l=   9 prim: OBJECT            :pkcs7-envelopedData
   15:d=1  hl=4 l= 301 cons: cont [ 0 ]
   19:d=2  hl=4 l= 297 cons: SEQUENCE
   23:d=3  hl=2 l=   1 prim: INTEGER           :00
   26:d=3  hl=3 l= 192 cons: SET
   29:d=4  hl=3 l= 189 cons: SEQUENCE
   32:d=5  hl=2 l=   1 prim: INTEGER           :00
   35:d=5  hl=2 l=  38 cons: SEQUENCE
   37:d=6  hl=2 l=  25 cons: SEQUENCE
   39:d=7  hl=2 l=  23 cons: SET
   41:d=8  hl=2 l=  21 cons: SEQUENCE
   43:d=9  hl=2 l=   3 prim: OBJECT            :commonName
   48:d=9  hl=2 l=  14 prim: UTF8STRING        :PKCS#7 example
   64:d=6  hl=2 l=   9 prim: INTEGER           :D28124BDCEECCCCC
   75:d=5  hl=2 l=  13 cons: SEQUENCE
   77:d=6  hl=2 l=   9 prim: OBJECT            :rsaEncryption
   88:d=6  hl=2 l=   0 prim: NULL
   90:d=5  hl=3 l= 128 prim: OCTET STRING      [HEX DUMP]:7A7782B34EC3C63ABAD847DC4C028AFB8C1072CB1A43154A7CBFB2CB5B31874FB0D5EF8607AE442762595CDB6C15BD6C0373F0CD21B25396AF457F3699BC87C09B7F2552BB7A9A03EE7EBD3FF8961A00D161BED2CF3214E491D18A26B3992DD1129AC2F4FC860A3E1A84C6F2115E788F6436EAD35A257FAD50D871D34E50F335
  221:d=3  hl=2 l=  97 cons: SEQUENCE
  223:d=4  hl=2 l=   9 prim: OBJECT            :pkcs7-data
  234:d=4  hl=2 l=  26 cons: SEQUENCE
  236:d=5  hl=2 l=   8 prim: OBJECT            :rc2-cbc
  246:d=5  hl=2 l=  14 cons: SEQUENCE
  248:d=6  hl=2 l=   2 prim: INTEGER           :A0
  252:d=6  hl=2 l=   8 prim: OCTET STRING      [HEX DUMP]:A05AF334241D3C3C
  262:d=4  hl=2 l=  56 prim: cont [ 0 ]

To decrypt a PKCS#7 envelopedData message we need access to the private key. In this example I will use the private key we've stored in the keyfile.key before. The OpenSSL smime command in used again:
openssl smime -decrypt -inform pem -in encrypted.p7 -inkey keyfile.key
This message won't be readable until decrypted again.


Signing a message in PKCS#7 format is almost as simple as encrypting it. Signing is done with the private key. This allows anyone who has access to the public key to verify that the message was signed by the owner of the matching private key and is used to proof the origin of a message.

Create a message to be signed:
echo "This message could only have been sent by me." > unsigned-original.txt

In this example I'm adding the -nodetach option. This option tells OpenSSL to include the original message in the PKCS#7 structure too. Besides the private key the certificate is also required for signing. This is used by OpenSSL to include a reference to the certificate in the signed message (an Issuer - SerialNumber combination, which should be unique). This reference enables the receiver to find the matching certificate, and thus public key. The command I'm using is as follows:
openssl smime -sign -nodetach -in unsigned-original.txt -out signed.p7 -outform pem -inkey keyfile.key -signer certificate.cer

The content is again PEM-encoded and can be parsed with asn1parse:
cat signed.p7
-----BEGIN PKCS7-----
-----END PKCS7-----

oap signed.p7
    0:d=0  hl=4 l=1046 cons: SEQUENCE
    4:d=1  hl=2 l=   9 prim: OBJECT            :pkcs7-signedData
   15:d=1  hl=4 l=1031 cons: cont [ 0 ]
   19:d=2  hl=4 l=1027 cons: SEQUENCE
   23:d=3  hl=2 l=   1 prim: INTEGER           :01
   26:d=3  hl=2 l=  11 cons: SET
   28:d=4  hl=2 l=   9 cons: SEQUENCE
   30:d=5  hl=2 l=   5 prim: OBJECT            :sha1
   37:d=5  hl=2 l=   0 prim: NULL
   39:d=3  hl=2 l=  62 cons: SEQUENCE
   41:d=4  hl=2 l=   9 prim: OBJECT            :pkcs7-data
   52:d=4  hl=2 l=  49 cons: cont [ 0 ]
   54:d=5  hl=2 l=  47 prim: OCTET STRING      :This message could only have been sent by me.

  103:d=3  hl=4 l= 516 cons: cont [ 0 ]
  107:d=4  hl=4 l= 512 cons: SEQUENCE
  111:d=5  hl=4 l= 361 cons: SEQUENCE
  115:d=6  hl=2 l=   3 cons: cont [ 0 ]
  117:d=7  hl=2 l=   1 prim: INTEGER           :02
  120:d=6  hl=2 l=   9 prim: INTEGER           :D28124BDCEECCCCC
  131:d=6  hl=2 l=  13 cons: SEQUENCE
  133:d=7  hl=2 l=   9 prim: OBJECT            :sha1WithRSAEncryption
  144:d=7  hl=2 l=   0 prim: NULL
  146:d=6  hl=2 l=  25 cons: SEQUENCE
  148:d=7  hl=2 l=  23 cons: SET
  150:d=8  hl=2 l=  21 cons: SEQUENCE
  152:d=9  hl=2 l=   3 prim: OBJECT            :commonName
  157:d=9  hl=2 l=  14 prim: UTF8STRING        :PKCS#7 example
  173:d=6  hl=2 l=  30 cons: SEQUENCE
  175:d=7  hl=2 l=  13 prim: UTCTIME           :130412203318Z
  190:d=7  hl=2 l=  13 prim: UTCTIME           :130512203318Z
  205:d=6  hl=2 l=  25 cons: SEQUENCE
  207:d=7  hl=2 l=  23 cons: SET
  209:d=8  hl=2 l=  21 cons: SEQUENCE
  211:d=9  hl=2 l=   3 prim: OBJECT            :commonName
  216:d=9  hl=2 l=  14 prim: UTF8STRING        :PKCS#7 example
  232:d=6  hl=3 l= 159 cons: SEQUENCE
  235:d=7  hl=2 l=  13 cons: SEQUENCE
  237:d=8  hl=2 l=   9 prim: OBJECT            :rsaEncryption
  248:d=8  hl=2 l=   0 prim: NULL
  250:d=7  hl=3 l= 141 prim: BIT STRING
  394:d=6  hl=2 l=  80 cons: cont [ 3 ]
  396:d=7  hl=2 l=  78 cons: SEQUENCE
  398:d=8  hl=2 l=  29 cons: SEQUENCE
  400:d=9  hl=2 l=   3 prim: OBJECT            :X509v3 Subject Key Identifier
  405:d=9  hl=2 l=  22 prim: OCTET STRING      [HEX DUMP]:0414B2ED2165623A8E3E5EB9652E781590C314EFC5B6
  429:d=8  hl=2 l=  31 cons: SEQUENCE
  431:d=9  hl=2 l=   3 prim: OBJECT            :X509v3 Authority Key Identifier
  436:d=9  hl=2 l=  24 prim: OCTET STRING      [HEX DUMP]:30168014B2ED2165623A8E3E5EB9652E781590C314EFC5B6
  462:d=8  hl=2 l=  12 cons: SEQUENCE
  464:d=9  hl=2 l=   3 prim: OBJECT            :X509v3 Basic Constraints
  469:d=9  hl=2 l=   5 prim: OCTET STRING      [HEX DUMP]:30030101FF
  476:d=5  hl=2 l=  13 cons: SEQUENCE
  478:d=6  hl=2 l=   9 prim: OBJECT            :sha1WithRSAEncryption
  489:d=6  hl=2 l=   0 prim: NULL
  491:d=5  hl=3 l= 129 prim: BIT STRING
  623:d=3  hl=4 l= 423 cons: SET
  627:d=4  hl=4 l= 419 cons: SEQUENCE
  631:d=5  hl=2 l=   1 prim: INTEGER           :01
  634:d=5  hl=2 l=  38 cons: SEQUENCE
  636:d=6  hl=2 l=  25 cons: SEQUENCE
  638:d=7  hl=2 l=  23 cons: SET
  640:d=8  hl=2 l=  21 cons: SEQUENCE
  642:d=9  hl=2 l=   3 prim: OBJECT            :commonName
  647:d=9  hl=2 l=  14 prim: UTF8STRING        :PKCS#7 example
  663:d=6  hl=2 l=   9 prim: INTEGER           :D28124BDCEECCCCC
  674:d=5  hl=2 l=   9 cons: SEQUENCE
  676:d=6  hl=2 l=   5 prim: OBJECT            :sha1
  683:d=6  hl=2 l=   0 prim: NULL
  685:d=5  hl=3 l= 216 cons: cont [ 0 ]
  688:d=6  hl=2 l=  24 cons: SEQUENCE
  690:d=7  hl=2 l=   9 prim: OBJECT            :contentType
  701:d=7  hl=2 l=  11 cons: SET
  703:d=8  hl=2 l=   9 prim: OBJECT            :pkcs7-data
  714:d=6  hl=2 l=  28 cons: SEQUENCE
  716:d=7  hl=2 l=   9 prim: OBJECT            :signingTime
  727:d=7  hl=2 l=  15 cons: SET
  729:d=8  hl=2 l=  13 prim: UTCTIME           :130412211115Z
  744:d=6  hl=2 l=  35 cons: SEQUENCE
  746:d=7  hl=2 l=   9 prim: OBJECT            :messageDigest
  757:d=7  hl=2 l=  22 cons: SET
  759:d=8  hl=2 l=  20 prim: OCTET STRING      [HEX DUMP]:B42A16215A4C519EF094C9ABD42D6C1B457685D6
  781:d=6  hl=2 l= 121 cons: SEQUENCE
  783:d=7  hl=2 l=   9 prim: OBJECT            :S/MIME Capabilities
  794:d=7  hl=2 l= 108 cons: SET
  796:d=8  hl=2 l= 106 cons: SEQUENCE
  798:d=9  hl=2 l=  11 cons: SEQUENCE
  800:d=10 hl=2 l=   9 prim: OBJECT            :aes-256-cbc
  811:d=9  hl=2 l=  11 cons: SEQUENCE
  813:d=10 hl=2 l=   9 prim: OBJECT            :aes-192-cbc
  824:d=9  hl=2 l=  11 cons: SEQUENCE
  826:d=10 hl=2 l=   9 prim: OBJECT            :aes-128-cbc
  837:d=9  hl=2 l=  10 cons: SEQUENCE
  839:d=10 hl=2 l=   8 prim: OBJECT            :des-ede3-cbc
  849:d=9  hl=2 l=  14 cons: SEQUENCE
  851:d=10 hl=2 l=   8 prim: OBJECT            :rc2-cbc
  861:d=10 hl=2 l=   2 prim: INTEGER           :80
  865:d=9  hl=2 l=  13 cons: SEQUENCE
  867:d=10 hl=2 l=   8 prim: OBJECT            :rc2-cbc
  877:d=10 hl=2 l=   1 prim: INTEGER           :40
  880:d=9  hl=2 l=   7 cons: SEQUENCE
  882:d=10 hl=2 l=   5 prim: OBJECT            :des-cbc
  889:d=9  hl=2 l=  13 cons: SEQUENCE
  891:d=10 hl=2 l=   8 prim: OBJECT            :rc2-cbc
  901:d=10 hl=2 l=   1 prim: INTEGER           :28
  904:d=5  hl=2 l=  13 cons: SEQUENCE
  906:d=6  hl=2 l=   9 prim: OBJECT            :rsaEncryption
  917:d=6  hl=2 l=   0 prim: NULL
  919:d=5  hl=3 l= 128 prim: OCTET STRING      [HEX DUMP]:7AB63445189B572CBA73883A57A43413D6D76116314DE54CAFA98713ED29997ECB6DB7DCD2CD4D668B51A445EDE3E36A9AFBD48625ACB7EC7BD2AFF3197CA36414F973218F5A7623A360D25B7755FC23809E62B2276418CFECB9A605213AF83F11A5859284B6861087804EAF4AF4FA2CBA685246280867E2C941EAA7619F4DB9


Verifying a PKCS#7 message is done to verify the authenticity of the message and to make sure it was sent by someone who has access to the private key. OpenSSL also tries to verify the certificate included in the message (or supplied on the commandline in some cases). Because I'm using a self signed certificate in this example the verification of the certificate will fail; because it's not signed by a trusted party.

openssl smime -verify -in signed.p7 -inform pem
Verification failure
2675740:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify error:pk7_smime.c:342:Verify error:self signed certificate

To overcome this we could add the -noverify option. This might look a bit weird (openssl verify -noverify...), but the message is still verified against the certificate. It's just the verification of the certificate itself that is skipped. Nevertheless this option should of course only be used when the full implications are understood!
openssl smime -verify -in signed.p7 -inform pem -noverify
This message could only have been sent by me.
Verification successful


OpenSSL is a verify powerful tool that can be a bit hard to operate. Depending on your (security) requirements some of the examples provided might be more suitable to your situation than others. Using these commands, or tailored versions, for troubleshooting or in testing environments should be OK. If however you plan on using these in a production environment, please, and don't take this lightly, consult someone with decent understanding of data encryption and key management!

openssl smime -encrypt -in plain-original.txt -outform pem -out encrypted.p7 certificate.cer

openssl smime -decrypt -inform pem -in encrypted.p7 -inkey keyfile.key

openssl smime -sign -nodetach -in unsigned-original.txt -out signed.p7 -outform pem -inkey keyfile.key -signer certificate.cer

openssl smime -verify -in signed.p7 -inform pem

Friday, March 30, 2012

Arduino CDP viewer - part 2

Following up on Arduino CDP viewer I have updated CdpSniffino on Github.

The retrieved information is now displayed on the attached LCD.
Issues regarding the unexplained freezes seem to be solved by not using SPI and I²C at the same time. Since the Arduino combined with the Ethernet Shield, still has enough free pins to connect the LCD, I haven't dug into this issue and just control the LCD with parallel connections.

Details on connecting the LCD can be found on the Arduino website - LiquidCrystal Tutorial.
I'm using pins 8, 7, 6, 5, 4, 3 and 2. These pins are configured in lcd_control.cpp.

To read two buttons, I'm using my own DebounceButton library, which you'll have to download to use the latest CdpSniffino too.

One button is used to scroll through the retrieved fields, and the other to scroll through the data in the field (when it's too long to display on the LCD).

As always, suggestions are welcome, but I currently don't have much time to implement new features.
I'm very interested to hear if you're using this tool and what you're using it for. So, if you are, please leave a comment.

Saturday, March 3, 2012

Arduino CDP viewer

Finally having a switch that sends CDP packets at home, I was looking for more information about the workings of this very informative protocol. CDP has saved me a lot time on finding the switch to configure, while working with Cisco IP telephones, and improper configured switches.

Wondering how I'd be able to gather CDP information with a small device like a cable tester, I came up with this Arduino CDP Sniffer - CdpSniffino. The CDP implementation is pretty complete, but I'm still working on a nice way to display the information.

You'll need an Arduino, and the Arduino Ethernet shield (or compatible network interface).
These are some idea's of how the information could be displayed on an LCD display (which I have laying around), using sample data from a Cisco IP phone sending CDP packets:

The LCD support is currently a work in progress, and somehow my Arduino freezes after running for a few minutes. On Github, checkout commit 020bf1e257, for a more stable, Serial-output only, version.

If you have any feature or improvement suggestions, please, let me know in the comments below.

Update: continued in Arduino CDP viewer - part 2

Monday, January 2, 2012

Manual verify PKCS#7 signed data with OpenSSL

Recently I was having some trouble with the verification of a signed message in PKCS#7 format. To troubleshoot why the library I was using kept rejecting the message I wanted to verify the signed message step by step, using OpenSSL. Below is a description of the steps to take to verify a PKCS#7 signed data message that is signed with a valid signature. Though I imagine these steps will apply to CMS messages for a big part too, I haven't looked into this.

Update 2013-04-12: this post was written to explain all the steps involved in the verification of a PKCS#7 message. Which might come in handy when troubleshooting compatibility issues. If however you're just interested in performing PKCS#7 encryption, decryption, signing and/or verification please have a look at my new post: PKCS#7 and OpenSSL. Which is also a good start when you are troubleshooting PKCS#7 communication.

Generate certificate
Generate a RSA test key and certificate, if you don't have one available.
openssl req -x509 -nodes -newkey rsa:1024 -keyout keyfile.key -out certificate.cer Generating a 1024 bit RSA private key .........++++++ .........................................++++++ writing new private key to 'keyfile.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]: State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []: Email Address []:

OpenSSL req is used to generate a self signed test certificate with an available private key. Here's an explanation of the used parameters.
-x509output a certificate instead of a request
-nodesdon't encrypt the private key
-newkey rsa:1024create a new RSA private key of 1024 bits
-keyout keyfile.keystore the private key in keyfile.key
-out certificate.cerstore the certificate in certificate.cer

Create a file to be signed
echo "Some text" > data.txt

Sign the data with keyfile and certificate
The signed data in this example is created with the command below.
(-md is available since OpenSSL 1.0.0)
openssl smime -sign -md sha1 \ -binary -nocerts -noattr \ -in data.txt -out data.txt.signed -outform der \ -inkey keyfile.key \ -signer certificate.cer

OpenSSL smime is used to sign the data. Here's an explanation of the used parameters.
-signinstruct OpenSSL to sign the data specified
-md sha1the message digest algorithm to use is SHA1
-binarytreat the data as binary, otherwise the data is interpreted as SMIME data
(in SMIME all newlines are replaced by 0x0D 0x0A)
-nocertsdon't include the certificate used for signing in the PKCS#7 message
-noattrdon't include any signed attributes
-in data.txtthe file to be signed is data.txt
-out data.txt.signedsave the signature in data.txt.signed
-outform dersave the signature in DER format
-inkey keyfile.keythe keyfile for the certificate that's to be used for signing is keyfile.key
-signer certificate.certhe certificate to sign the data with is certificate.cer

Find offset of hex data
OpenSSL asn1parse is used to allocate the signature in the PKCS#7 message. The PKCS#7 message in data.txt.signed has the following (simplified) structure.

contentTypesignedData (1.2.840.113549.1.7.2)
DigestAlgorithmIdentifierSHA1 (
contentTypedata (1.2.840.113549.1.7.1)
issuerC=AU, S=Some-State, O = Internet Widgits Pty Ltd
serialNumberHEX SERIAL
digestAlgorithmSHA1 (
digestEncryptionAlgorithmrsaEncryption (1.2.840.113549.1.1.1, depends on certificate used)
encryptedDigestBINARY DATA

To locate the signature, issue the following command.
openssl asn1parse -inform der -in data.txt.signed 0:d=0 hl=4 l= 298 cons: SEQUENCE 4:d=1 hl=2 l= 9 prim: OBJECT :pkcs7-signedData 15:d=1 hl=4 l= 283 cons: cont [ 0 ] 19:d=2 hl=4 l= 279 cons: SEQUENCE 23:d=3 hl=2 l= 1 prim: INTEGER :01 26:d=3 hl=2 l= 11 cons: SET 28:d=4 hl=2 l= 9 cons: SEQUENCE 30:d=5 hl=2 l= 5 prim: OBJECT :sha1 37:d=5 hl=2 l= 0 prim: NULL 39:d=3 hl=2 l= 11 cons: SEQUENCE 41:d=4 hl=2 l= 9 prim: OBJECT :pkcs7-data 52:d=3 hl=3 l= 247 cons: SET 55:d=4 hl=3 l= 244 cons: SEQUENCE 58:d=5 hl=2 l= 1 prim: INTEGER :01 61:d=5 hl=2 l= 82 cons: SEQUENCE 63:d=6 hl=2 l= 69 cons: SEQUENCE 65:d=7 hl=2 l= 11 cons: SET 67:d=8 hl=2 l= 9 cons: SEQUENCE 69:d=9 hl=2 l= 3 prim: OBJECT :countryName 74:d=9 hl=2 l= 2 prim: PRINTABLESTRING :AU 78:d=7 hl=2 l= 19 cons: SET 80:d=8 hl=2 l= 17 cons: SEQUENCE 82:d=9 hl=2 l= 3 prim: OBJECT :stateOrProvinceName 87:d=9 hl=2 l= 10 prim: UTF8STRING :Some-State 99:d=7 hl=2 l= 33 cons: SET 101:d=8 hl=2 l= 31 cons: SEQUENCE 103:d=9 hl=2 l= 3 prim: OBJECT :organizationName 108:d=9 hl=2 l= 24 prim: UTF8STRING :Internet Widgits Pty Ltd 134:d=6 hl=2 l= 9 prim: INTEGER :84166567E339E7BC 145:d=5 hl=2 l= 9 cons: SEQUENCE 147:d=6 hl=2 l= 5 prim: OBJECT :sha1 154:d=6 hl=2 l= 0 prim: NULL 156:d=5 hl=2 l= 13 cons: SEQUENCE 158:d=6 hl=2 l= 9 prim: OBJECT :rsaEncryption 169:d=6 hl=2 l= 0 prim: NULL 171:d=5 hl=3 l= 128 prim: OCTET STRING [HEX DUMP]:694CDAA975D17A35512ECA9D22373CFE28A997C96B129557B014FFB492B525068FE94F3BBD124E82C909CA7E2119AC4526FAB03DAD8C7E9C775599B224CB1AF39936C0D65669B0B39460CE29E13F97BC50EE56DB5357DA4EFDA5D850CDF8609643ACA54CE0295BC99375B1F552058E1CB0A69EFD2C43CF8BF5DB7315819DB03C

OpenSSL asn1parse is used to parse the ASN.1 structure of the PKCS#7 message. Here's an explanation of the used parameters.
-inform derinstruct OpenSSL to read the specified file as DER encoded data
-in data.txt.signedthe file to parse is data.txt.signed

Extract binary RSA encrypted hash
Note the start, header length and data length of the encrypted data (highlighted).
171:d=5 hl=3 l= 128 prim: OCTET STRING [HEX

Use dd to copy the signature part of the PKCS#7 message to a separate file. Skip the offset (171) and header (length: 3) and extract the data bytes (128).
dd if=data.txt.signed of=signed-sha1.bin bs=1 skip=$[ 171 + 3 ] count=128 128+0 records in 128+0 records out 128 bytes (128 B) copied, 0.00390004 s, 32.8 kB/s

Verify the extracted data
The data in signed-sha1.bin should match the octet string of the asn1parse from before.
hexdump -C signed-sha1.bin 00000000 69 4c da a9 75 d1 7a 35 51 2e ca 9d 22 37 3c fe |iL..u.z5Q..."7<.| 00000010 28 a9 97 c9 6b 12 95 57 b0 14 ff b4 92 b5 25 06 |(...k..W......%.| 00000020 8f e9 4f 3b bd 12 4e 82 c9 09 ca 7e 21 19 ac 45 |..O;..N....~!..E| 00000030 26 fa b0 3d ad 8c 7e 9c 77 55 99 b2 24 cb 1a f3 |&..=..~.wU..$...| 00000040 99 36 c0 d6 56 69 b0 b3 94 60 ce 29 e1 3f 97 bc |.6..Vi...`.).?..| 00000050 50 ee 56 db 53 57 da 4e fd a5 d8 50 cd f8 60 96 |P.V.SW.N...P..`.| 00000060 43 ac a5 4c e0 29 5b c9 93 75 b1 f5 52 05 8e 1c |C..L.)[..u..R...| 00000070 b0 a6 9e fd 2c 43 cf 8b f5 db 73 15 81 9d b0 3c |....,C....s....<| 00000080

Extract the public key from the certificate
Since the signature is encrypted with RSA, and OpenSSL requires a separate key file to perform RSA encryption, the following command is used to extract the public key from the certificate for use with rsautl.
openssl x509 -inform pem -in certificate.cer -noout -pubkey > pubkey.pem

OpenSSL x509 is used to extract the public key. Here's an explanation of the used parameters.
-inform pemdepending on your certificate use pem or der to instruct OpenSSL to read the specified file as PEM or DER encoded data
-in certificate.certhe file to parse is certificate.cer
-nooutdon't output the certificate (which is default behavior of openssl x509)
-pubkeyoutput the public key
> pubkey.pemredirect the output of this command to the file pubkey.pem

Verify the signature
Verifying the signature with openssl will return an ASN1 object with the hash.
openssl rsautl -verify -pubin -inkey pubkey.pem < signed-sha1.bin > verified.bin

OpenSSL rsautl is used to 'verify' (decrypt with public key) the encrypted signature. Here's an explanation of the used parameters.
-verifyinstruct OpenSSL rsautl to perform verification (decrypting with public key)
-pubinthe specified key file is a public key
-inkey pubkey.pemthe key file to use is pubkey.pem
< signed-sha1.binread signed-sha1.bin to the input of this command
> verified.binredirect the output of this command to the file verified.bin

The file created by decrypting the encrypted signature contains the message digest and associated information. This file is, again, in ASN.1 format, so OpenSSL can be used to parse it as demonstrated below.
hexdump -C verified.bin 00000000 30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 5a |0!0...+........Z| 00000010 08 92 4b 0e f1 cc cf b5 de 1d 94 e3 d7 5c 38 dc |..K..........\8.| 00000020 0d 3c 79 |.<y| 00000023 openssl asn1parse -inform der -in verified.bin 0:d=0 hl=2 l= 33 cons: SEQUENCE 2:d=1 hl=2 l= 9 cons: SEQUENCE 4:d=2 hl=2 l= 5 prim: OBJECT :sha1 11:d=2 hl=2 l= 0 prim: NULL 13:d=1 hl=2 l= 20 prim: OCTET STRING [HEX DUMP]:5A08924B0EF1CCCFB5DE1D94E3D75C38DC0D3C79

The hash in this object should be equal to the hash of the file that was signed
sha1sum.exe data.txt 5a08924b0ef1cccfb5de1d94e3d75c38dc0d3c79 *data.txt