#!/bin/sh
# Make a 72-bit password (12 characters, 6 bits per char)
dd if=/dev/urandom count=1 2>/dev/null | base64 | head -1 | cut -c4-15
September 20, 2013
C function to convert hex to binary
A simple C function to convert hex to binary
#include <ctype.h>
inline int cval(char c) {
if (c>='a') return c-'a'+0x0a;
if (c>='A') return c-'A'+0x0a;
return c-'0';
}
/* return value: number of bytes in out, <=0 if error */
int hex2bin(char *str, unsigned char *out){
int i;
for(i = 0; str[i] && str[i+1]; i+=2){
if (!isxdigit(str[i])&& !isxdigit(str[i+1]))
return -1;
out[i/2] = (cval(str[i])<<4) + cval(str[i+1]);
}
return i/2;
}
TLS PSK, TLS SRP, and TLS JPAKE
As of time of this post, there are three common password based authentication for TLS:
- TLS-PSK (Pre-Shared Key), RFC 4279
- TLS-SRP (Secure Remote Password), RFC 5054
- TLS-JPAKE, implemented in OpenSSL, not in RFC (yet)
TLS-PSK uses the pre-shared key to generate the TLS premaster key, which is then used to generate master key and session key. It is the simplest one, but the user has to safeguard the PSK.
TLS-SRP is more secure, in that it only stores a password verifier value, not the password itself. It would be a nice upgrade to replace TLS-PSK. Unfortunately, some rumors about potential patent problems (although the authors of SRP, Stanford University, has grant free-use of the patent) prevent it from being adopted in a large scale. For example, Fedora, and therefore Redhat, removes TLS-SRP from its OpenSSL libraries because of this. (Fedora script that removes SRP from openssl). Given that RHEL is the de-facto standard for enterprise Linux, this makes it hard to use TLS-SRP in commercial environment.
TLS-JPAKE is somewhat similar in what it tries to achieve. However, there does not seem to be a standard RFC for it yet, so inter-operability is a question. Also, according to OpenSSL, J-PAKE is still experimental and not activated as default.
For now, we will have to stick to the old plain TLS-PSK, which is a well-defined standard and has been implemented widely.
September 17, 2013
vim tags file search path
add the following to your .vimrc file:
set tags=./tags;
Notice ";" after tags. That's important. That tells Vim to search tags in the current directory, and if not found, search parent directory, and continue up until found. Isn't that great?
set tags=./tags;
Notice ";" after tags. That's important. That tells Vim to search tags in the current directory, and if not found, search parent directory, and continue up until found. Isn't that great?
TLS PSK server using openssl library
A simple TLS-PSK server program that based on the openssl library. This is based on the s_server app from openssl, removing all the unused parts and merge all code into one simple file.
Source:
Updated with working link:
https://bitbucket.org/tiebingzhang/tls-psk-server-client-example
Source:
Updated with working link:
https://bitbucket.org/tiebingzhang/tls-psk-server-client-example
September 13, 2013
Java Bouncy Castle TLS PSK example
This is an example how to use the Bouncy Castle library to write a TLS-PSK client. The server was tested with was an openssl server (openssl s_server). Keep in mind that I do not write Java program regularly, so you may find some style/usage not the best.
Source:
Source:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.security.SecureRandom;
import java.security.Provider;
import java.security.Security;
import javax.xml.bind.DatatypeConverter;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.crypto.tls.AlertLevel;
import org.bouncycastle.crypto.tls.CipherSuite;
import org.bouncycastle.crypto.tls.DefaultTlsClient;
import org.bouncycastle.crypto.tls.ServerOnlyTlsAuthentication;
import org.bouncycastle.crypto.tls.TlsAuthentication;
import org.bouncycastle.crypto.tls.TlsClientProtocol;
import org.bouncycastle.crypto.tls.TlsPSKIdentity;
import org.bouncycastle.crypto.tls.PSKTlsClient;
import org.bouncycastle.util.io.Streams;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
* A simple test designed to conduct a TLS-PSK handshake with an external TLS server.
*/
public class PSKTlsClientTest
{
static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
static class Z_PSKIdentity implements TlsPSKIdentity {
void Z_PSKIdentity(){};
public void skipIdentityHint(){
System.out.println("skipIdentityHint called\n");
}
public void notifyIdentityHint(byte[] PSK_identity_hint){
System.out.println("notifyIdentityHint called\n");
}
public byte[] getPSKIdentity(){
return "Client_identity".getBytes();
}
public byte[] getPSK(){
return DatatypeConverter.parseHexBinary("1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A");
}
}
public static void main(String[] args)
throws Exception
{
Z_PSKIdentity pskIdentity = new Z_PSKIdentity();
Security.addProvider(new BouncyCastleProvider());
Socket socket = new Socket(InetAddress.getByName("192.168.1.201"), 10443);
SecureRandom secureRandom = new SecureRandom();
TlsClientProtocol protocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(),
secureRandom);
MyPSKTlsClient client = new MyPSKTlsClient(pskIdentity);
protocol.connect(client);
OutputStream output = protocol.getOutputStream();
output.write("GET / HTTP/1.1\r\n\r\n".getBytes("UTF-8"));
InputStream input = protocol.getInputStream();
System.out.println(convertStreamToString(input));
protocol.close();
socket.close();
}
static class MyPSKTlsClient
extends PSKTlsClient
{
public MyPSKTlsClient(TlsPSKIdentity id){
super(id);
}
public void notifyAlertRaised(short alertLevel, short alertDescription, String message, Exception cause)
{
PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out;
out.println("TLS client raised alert (AlertLevel." + alertLevel + ", AlertDescription." + alertDescription + ")");
if (message != null) {
out.println(message);
}
if (cause != null) {
cause.printStackTrace(out);
}
}
public void notifyAlertReceived(short alertLevel, short alertDescription)
{
PrintStream out = (alertLevel == AlertLevel.fatal) ? System.err : System.out;
out.println("TLS client received alert (AlertLevel." + alertLevel + ", AlertDescription."
+ alertDescription + ")");
}
public TlsAuthentication getAuthentication()
throws IOException
{
return new ServerOnlyTlsAuthentication()
{
public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate)
throws IOException
{
System.out.println("in getAuthentication");
}
};
}
}
}
The simple Makefile (I installed gnuwin32 so my system has "rm" )
all:
javac -cp "jce-jdk13-149.jar;." PSKTlsClientTest.java
jar -cfm tls.jar manifest.txt PSKTlsClient*.class
run:
run.bat -jar tls.jar
clean:
rm -f PskTlsClient*.class PskTlsClient*.jar
The Server side. Keep in mind that openssl s_server by default uses id "Client_identity". The hint is just a hint. It does not change the fact that the serve requires the client to provide the id "Client_identity". Of course this can be changed if you make your own application. So below you can use anything for the psk_hint, or even omit the argument.
$ cat psk_server.sh
openssl s_server \
-psk 1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A \
-psk_hint Client_identity\
-cipher PSK-AES256-CBC-SHA \
-debug -state -nocert -accept 10443 -tls1 -www
manifest.txt file
Main-Class: PSKTlsClientTest
Class-Path: . jce-jdk13-149.jar
run.bat file (The host is Windows 7)
java -cp "jce-jdk13-149.jar;." %*