1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-10-15 11:26:40 +03:00

* SNI added

* Some non-C sample code updated.

git-svn-id: svn://svn.code.sf.net/p/axtls/code/trunk@271 9a5d90b5-6617-0410-8a86-bb477d3ed2e3
This commit is contained in:
cameronrich
2016-12-12 19:27:38 +00:00
committed by Ivan Grokhotkov
parent a68324f17c
commit 425067abe6
18 changed files with 5701 additions and 48 deletions

105
bindings/Config.in Normal file
View File

@@ -0,0 +1,105 @@
#
# For a description of the syntax of this configuration file,
# see scripts/config/Kconfig-language.txt
#
menu "Language Bindings"
config CONFIG_BINDINGS
bool "Create language bindings"
default n
help
axTLS supports language bindings in C#, VB.NET, Java and Perl.
Select Y here if you want to build the various language bindings.
config CONFIG_CSHARP_BINDINGS
bool "Create C# bindings"
default n
depends on CONFIG_BINDINGS
help
Build C# bindings.
This requires .NET to be installed on Win32 platforms and mono to be
installed on all other platforms.
config CONFIG_VBNET_BINDINGS
bool "Create VB.NET bindings"
default n
depends on CONFIG_BINDINGS
help
Build VB.NET bindings.
This requires the .NET to be installed and is only built under Win32
platforms.
menu ".Net Framework"
depends on CONFIG_CSHARP_BINDINGS || CONFIG_VBNET_BINDINGS
config CONFIG_DOT_NET_FRAMEWORK_BASE
string "Location of .NET Framework"
default "c:\\WINDOWS\\Microsoft.NET\\Framework\\v2.0.50727"
endmenu
config CONFIG_JAVA_BINDINGS
bool "Create Java bindings"
default n
depends on CONFIG_BINDINGS
help
Build Java bindings.
Current Issues (see README):
* Needs Java 1.4 or better.
* If building under Win32 it will use the Win32 JDK.
menu "Java Home"
depends on CONFIG_JAVA_BINDINGS
config CONFIG_JAVA_HOME
string "Location of JDK"
default "c:\\Program Files\\Java\\jdk1.5.0_06" if CONFIG_PLATFORM_WIN32 || CONFIG_PLATFORM_CYGWIN
default "/usr/lib/jvm/java-7-openjdk-amd64" if !CONFIG_PLATFORM_WIN32 && !CONFIG_PLATFORM_CYGWIN
depends on CONFIG_JAVA_BINDINGS
help
The location of Sun's JDK.
endmenu
config CONFIG_PERL_BINDINGS
bool "Create Perl bindings"
default n
depends on CONFIG_BINDINGS
help
Build Perl bindings.
Current Issues (see README):
* 64 bit versions don't work at present.
* libperl.so needs to be in the shared library path.
menu "Perl Home"
depends on CONFIG_PERL_BINDINGS && CONFIG_PLATFORM_WIN32
config CONFIG_PERL_CORE
string "Location of Perl CORE"
default "c:\\perl\\lib\\CORE"
help:
works with ActiveState
"http://www.activestate.com/Products/ActivePerl"
config CONFIG_PERL_LIB
string "Name of Perl Library"
default "perl58.lib"
endmenu
config CONFIG_LUA_BINDINGS
bool "Create Lua bindings"
default n
depends on CONFIG_BINDINGS && !CONFIG_PLATFORM_WIN32
help
Build Lua bindings (see www.lua.org).
menu "Lua Home"
depends on CONFIG_LUA_BINDINGS
config CONFIG_LUA_CORE
string "Location of Lua CORE"
default "/usr/local"
help:
If the Lua exists on another directory then this needs to be changed
endmenu
endmenu

491
bindings/csharp/axTLS.cs Normal file
View File

@@ -0,0 +1,491 @@
/*
* Copyright (c) 2007-2016, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* A wrapper around the unmanaged interface to give a semi-decent C# API
*/
using System;
using System.Runtime.InteropServices;
using System.Net.Sockets;
/**
* @defgroup csharp_api C# API.
*
* Ensure that the appropriate Dispose() methods are called when finished with
* various objects - otherwise memory leaks will result.
* @{
*/
namespace axTLS
{
/**
* @class SSL
* @ingroup csharp_api
* @brief A representation of an SSL connection.
*/
public class SSL
{
public IntPtr m_ssl; /**< A pointer to the real SSL type */
/**
* @brief Store the reference to an SSL context.
* @param ip [in] A reference to an SSL object.
*/
public SSL(IntPtr ip)
{
m_ssl = ip;
}
/**
* @brief Free any used resources on this connection.
*
* A "Close Notify" message is sent on this connection (if possible).
* It is up to the application to close the socket.
*/
public void Dispose()
{
axtls.ssl_free(m_ssl);
}
/**
* @brief Return the result of a handshake.
* @return SSL_OK if the handshake is complete and ok.
* @see ssl.h for the error code list.
*/
public int HandshakeStatus()
{
return axtls.ssl_handshake_status(m_ssl);
}
/**
* @brief Return the SSL cipher id.
* @return The cipher id which is one of:
* - SSL_AES128_SHA (0x2f)
* - SSL_AES256_SHA (0x35)
* - SSL_AES128_SHA256 (0x3c)
* - SSL_AES256_SHA256 (0x3d)
*/
public byte GetCipherId()
{
return axtls.ssl_get_cipher_id(m_ssl);
}
/**
* @brief Get the session id for a handshake.
*
* This will be a 32 byte sequence and is available after the first
* handshaking messages are sent.
* @return The session id as a 32 byte sequence.
* @note A SSLv23 handshake may have only 16 valid bytes.
*/
public byte[] GetSessionId()
{
IntPtr ptr = axtls.ssl_get_session_id(m_ssl);
byte sess_id_size = axtls.ssl_get_session_id_size(m_ssl);
byte[] result = new byte[sess_id_size];
Marshal.Copy(ptr, result, 0, sess_id_size);
return result;
}
/**
* @brief Retrieve an X.509 distinguished name component.
*
* When a handshake is complete and a certificate has been exchanged,
* then the details of the remote certificate can be retrieved.
*
* This will usually be used by a client to check that the server's
* common name matches the URL.
*
* A full handshake needs to occur for this call to work.
*
* @param component [in] one of:
* - SSL_X509_CERT_COMMON_NAME
* - SSL_X509_CERT_ORGANIZATION
* - SSL_X509_CERT_ORGANIZATIONAL_NAME
* - SSL_X509_CA_CERT_COMMON_NAME
* - SSL_X509_CA_CERT_ORGANIZATION
* - SSL_X509_CA_CERT_ORGANIZATIONAL_NAME
* @return The appropriate string (or null if not defined)
*/
public string GetCertificateDN(int component)
{
return axtls.ssl_get_cert_dn(m_ssl, component);
}
}
/**
* @class SSLUtil
* @ingroup csharp_api
* @brief Some global helper functions.
*/
public class SSLUtil
{
/**
* @brief Return the build mode of the axTLS project.
* @return The build mode is one of:
* - SSL_BUILD_SERVER_ONLY
* - SSL_BUILD_ENABLE_VERIFICATION
* - SSL_BUILD_ENABLE_CLIENT
* - SSL_BUILD_FULL_MODE
*/
public static int BuildMode()
{
return axtls.ssl_get_config(axtls.SSL_BUILD_MODE);
}
/**
* @brief Return the number of chained certificates that the
* client/server supports.
* @return The number of supported server certificates.
*/
public static int MaxCerts()
{
return axtls.ssl_get_config(axtls.SSL_MAX_CERT_CFG_OFFSET);
}
/**
* @brief Return the number of CA certificates that the client/server
* supports.
* @return The number of supported CA certificates.
*/
public static int MaxCACerts()
{
return axtls.ssl_get_config(axtls.SSL_MAX_CA_CERT_CFG_OFFSET);
}
/**
* @brief Indicate if PEM is supported.
* @return true if PEM supported.
*/
public static bool HasPEM()
{
return axtls.ssl_get_config(axtls.SSL_HAS_PEM) > 0 ? true : false;
}
/**
* @brief Display the text string of the error.
* @param error_code [in] The integer error code.
*/
public static void DisplayError(int error_code)
{
axtls.ssl_display_error(error_code);
}
/**
* @brief Return the version of the axTLS project.
*/
public static string Version()
{
return axtls.ssl_version();
}
}
/**
* @class SSLCTX
* @ingroup csharp_api
* @brief A base object for SSLServer/SSLClient.
*/
public class SSLCTX
{
/**
* @brief A reference to the real client/server context.
*/
protected IntPtr m_ctx;
/**
* @brief Establish a new client/server context.
*
* This function is called before any client/server SSL connections are
* made. If multiple threads are used, then each thread will have its
* own SSLCTX context. Any number of connections may be made with a
* single context.
*
* Each new connection will use the this context's private key and
* certificate chain. If a different certificate chain is required,
* then a different context needs to be be used.
*
* @param options [in] Any particular options. At present the options
* supported are:
* - SSL_SERVER_VERIFY_LATER (client only): Don't stop a handshake if
* the server authentication fails. The certificate can be
* authenticated later with a call to VerifyCert().
* - SSL_CLIENT_AUTHENTICATION (server only): Enforce client
* authentication i.e. each handshake will include a "certificate
* request" message from the server.
* - SSL_DISPLAY_BYTES (full mode build only): Display the byte
* sequences during the handshake.
* - SSL_DISPLAY_STATES (full mode build only): Display the state
* changes during the handshake.
* - SSL_DISPLAY_CERTS (full mode build only): Display the
* certificates that are passed during a handshake.
* - SSL_DISPLAY_RSA (full mode build only): Display the RSA key
* details that are passed during a handshake.
* @param num_sessions [in] The number of sessions to be used for
* session caching. If this value is 0, then there is no session
* caching.
* @return A client/server context.
*/
protected SSLCTX(uint options, int num_sessions)
{
m_ctx = axtls.ssl_ctx_new(options, num_sessions);
}
/**
* @brief Remove a client/server context.
*
* Frees any used resources used by this context. Each connection will
* be sent a "Close Notify" alert (if possible).
*/
public void Dispose()
{
axtls.ssl_ctx_free(m_ctx);
}
/**
* @brief Read the SSL data stream.
* @param ssl [in] An SSL object reference.
* @param in_data [out] After a successful read, the decrypted data
* will be here. It will be null otherwise.
* @return The number of decrypted bytes:
* - if > 0, then the handshaking is complete and we are returning the
* number of decrypted bytes.
* - SSL_OK if the handshaking stage is successful (but not yet
* complete).
* - < 0 if an error.
* @see ssl.h for the error code list.
* @note Use in_data before doing any successive ssl calls.
*/
public int Read(SSL ssl, out byte[] in_data)
{
IntPtr ptr = IntPtr.Zero;
int ret = axtls.ssl_read(ssl.m_ssl, ref ptr);
if (ret > axtls.SSL_OK)
{
in_data = new byte[ret];
Marshal.Copy(ptr, in_data, 0, ret);
}
else
{
in_data = null;
}
return ret;
}
/**
* @brief Write to the SSL data stream.
* @param ssl [in] An SSL obect reference.
* @param out_data [in] The data to be written
* @return The number of bytes sent, or if < 0 if an error.
* @see ssl.h for the error code list.
*/
public int Write(SSL ssl, byte[] out_data)
{
return axtls.ssl_write(ssl.m_ssl, out_data, out_data.Length);
}
/**
* @brief Write to the SSL data stream.
* @param ssl [in] An SSL obect reference.
* @param out_data [in] The data to be written
* @param out_len [in] The number of bytes to be written
* @return The number of bytes sent, or if < 0 if an error.
* @see ssl.h for the error code list.
*/
public int Write(SSL ssl, byte[] out_data, int out_len)
{
return axtls.ssl_write(ssl.m_ssl, out_data, out_len);
}
/**
* @brief Find an ssl object based on a Socket reference.
*
* Goes through the list of SSL objects maintained in a client/server
* context to look for a socket match.
* @param s [in] A reference to a <A HREF="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemnetsocketssocketclasstopic.asp">Socket</A> object.
* @return A reference to the SSL object. Returns null if the object
* could not be found.
*/
public SSL Find(Socket s)
{
int client_fd = s.Handle.ToInt32();
return new SSL(axtls. ssl_find(m_ctx, client_fd));
}
/**
* @brief Authenticate a received certificate.
*
* This call is usually made by a client after a handshake is complete
* and the context is in SSL_SERVER_VERIFY_LATER mode.
* @param ssl [in] An SSL object reference.
* @return SSL_OK if the certificate is verified.
*/
public int VerifyCert(SSL ssl)
{
return axtls.ssl_verify_cert(ssl.m_ssl);
}
/**
* @brief Force the client to perform its handshake again.
*
* For a client this involves sending another "client hello" message.
* For the server is means sending a "hello request" message.
*
* This is a blocking call on the client (until the handshake
* completes).
* @param ssl [in] An SSL object reference.
* @return SSL_OK if renegotiation instantiation was ok
*/
public int Renegotiate(SSL ssl)
{
return axtls.ssl_renegotiate(ssl.m_ssl);
}
/**
* @brief Load a file into memory that is in binary DER or ASCII PEM
* format.
*
* These are temporary objects that are used to load private keys,
* certificates etc into memory.
* @param obj_type [in] The format of the file. Can be one of:
* - SSL_OBJ_X509_CERT (no password required)
* - SSL_OBJ_X509_CACERT (no password required)
* - SSL_OBJ_RSA_KEY (AES128/AES256 PEM encryption supported)
* - SSL_OBJ_P8 (RC4-128 encrypted data supported)
* - SSL_OBJ_P12 (RC4-128 encrypted data supported)
*
* PEM files are automatically detected (if supported).
* @param filename [in] The location of a file in DER/PEM format.
* @param password [in] The password used. Can be null if not required.
* @return SSL_OK if all ok
*/
public int ObjLoad(int obj_type, string filename, string password)
{
return axtls.ssl_obj_load(m_ctx, obj_type, filename, password);
}
/**
* @brief Transfer binary data into the object loader.
*
* These are temporary objects that are used to load private keys,
* certificates etc into memory.
* @param obj_type [in] The format of the memory data.
* @param data [in] The binary data to be loaded.
* @param len [in] The amount of data to be loaded.
* @param password [in] The password used. Can be null if not required.
* @return SSL_OK if all ok
*/
public int ObjLoad(int obj_type, byte[] data, int len, string password)
{
return axtls.ssl_obj_memory_load(m_ctx, obj_type,
data, len, password);
}
}
/**
* @class SSLServer
* @ingroup csharp_api
* @brief The server context.
*
* All server connections are started within a server context.
*/
public class SSLServer : SSLCTX
{
/**
* @brief Start a new server context.
*
* @see SSLCTX for details.
*/
public SSLServer(uint options, int num_sessions) :
base(options, num_sessions) {}
/**
* @brief Establish a new SSL connection to an SSL client.
*
* It is up to the application to establish the initial socket
* connection.
*
* Call Dispose() when the connection is to be removed.
* @param s [in] A reference to a <A HREF="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemnetsocketssocketclasstopic.asp">Socket</A> object.
* @return An SSL object reference.
*/
public SSL Connect(Socket s)
{
int client_fd = s.Handle.ToInt32();
return new SSL(axtls.ssl_server_new(m_ctx, client_fd));
}
}
/**
* @class SSLClient
* @ingroup csharp_api
* @brief The client context.
*
* All client connections are started within a client context.
*/
public class SSLClient : SSLCTX
{
/**
* @brief Start a new client context.
*
* @see SSLCTX for details.
*/
public SSLClient(uint options, int num_sessions) :
base(options, num_sessions) {}
/**
* @brief Establish a new SSL connection to an SSL server.
*
* It is up to the application to establish the initial socket
* connection.
*
* This is a blocking call - it will finish when the handshake is
* complete (or has failed).
*
* Call Dispose() when the connection is to be removed.
* @param s [in] A reference to a <A HREF="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemnetsocketssocketclasstopic.asp">Socket</A> object.
* @param session_id [in] A 32 byte session id for session resumption.
* This can be null if no session resumption is not required.
* @return An SSL object reference. Use SSL.handshakeStatus() to check
* if a handshake succeeded.
*/
public SSL Connect(Socket s, byte[] session_id)
{
int client_fd = s.Handle.ToInt32();
byte sess_id_size = (byte)(session_id != null ?
session_id.Length : 0);
return new SSL(axtls.ssl_client_new(m_ctx, client_fd, session_id,
sess_id_size));
}
}
}
/** @} */

View File

@@ -0,0 +1,392 @@
#!/usr/bin/perl
#
# Copyright (c) 2007, Cameron Rich
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the axTLS project nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#===============================================================
# Transforms function signature into SWIG format
sub transformSignature
{
foreach $item (@_)
{
$line =~ s/STDCALL //g;
$line =~ s/EXP_FUNC/extern/g;
# make API Java more 'byte' friendly
$line =~ s/uint32_t/int/g;
$line =~ s/const uint8_t \* /const unsigned char \* /g;
$line =~ s/\(void\)/()/g;
if ($ARGV[0] eq "-java")
{
$line =~ s/.*ssl_read.*//g;
$line =~ s/const uint8_t \*(\w+)/const signed char $1\[\]/g;
$line =~ s/uint8_t/signed char/g;
}
elsif ($ARGV[0] eq "-perl")
{
$line =~ s/const uint8_t \*(\w+)/const unsigned char $1\[\]/g;
$line =~ s/uint8_t/unsigned char/g;
}
else # lua
{
$line =~ s/const uint8_t \*session_id/const unsigned char session_id\[\]/g;
$line =~ s/const uint8_t \*\w+/unsigned char *INPUT/g;
$line =~ s/uint8_t/unsigned char/g;
}
}
return $line;
}
# Parse input file
sub parseFile
{
foreach $line (@_)
{
next if $line =~ /ssl_x509_create/; # ignore for now
# test for a #define
if (!$skip && $line =~ m/^#define/)
{
$splitDefine = 1 if $line =~ m/\\$/;
print DATA_OUT $line;
# check line is not split
next if $splitDefine == 1;
}
# pick up second line of #define statement
if ($splitDefine)
{
print DATA_OUT $line;
# check line is not split
$splitDefine = ($line =~ m/\\$/);
next;
}
# test for function declaration
if (!$skip && $line =~ /EXP_FUNC/ && $line !~/\/\*/)
{
$line = transformSignature($line);
$splitFunctionDeclaration = $line !~ /;/;
print DATA_OUT $line;
next;
}
if ($splitFunctionDeclaration)
{
$line = transformSignature($line);
$splitFunctionDeclaration = $line !~ /;/;
print DATA_OUT $line;
next;
}
}
}
#===============================================================
# Determine which module to build from cammand-line options
use strict;
use Getopt::Std;
my $module;
my $interfaceFile;
my $data_file;
my $skip;
my $splitLine;
my @raw_data;
if (not defined $ARGV[0])
{
die "Usage: $0 [-java | -perl | -lua]\n";
}
if ($ARGV[0] eq "-java")
{
print "Generating Java interface file\n";
$module = "axtlsj";
$interfaceFile = "java/axTLSj.i";
}
elsif ($ARGV[0] eq "-perl")
{
print "Generating Perl interface file\n";
$module = "axtlsp";
$interfaceFile = "perl/axTLSp.i";
}
elsif ($ARGV[0] eq "-lua")
{
print "Generating lua interface file\n";
$module = "axtlsl";
$interfaceFile = "lua/axTLSl.i";
}
else
{
die "Usage: $0 [-java | -perl | -lua]\n";
}
# Input file required to generate SWIG interface file.
$data_file = "../ssl/ssl.h";
# Open input files
open(DATA_IN, $data_file) || die("Could not open file ($data_file)!");
@raw_data = <DATA_IN>;
# Open output file
open(DATA_OUT, ">$interfaceFile") || die("Cannot Open File");
#
# I wish I could say it was easy to generate the Perl/Java/Lua bindings,
# but each had their own set of challenges... :-(.
#
print DATA_OUT << "END";
%module $module\n
/* include our own header */
%inline %{
#include "ssl.h"
%}
%include "typemaps.i"
/* Some SWIG magic to make the API a bit more Java friendly */
#ifdef SWIGJAVA
%apply long { SSL * };
%apply long { SSL_CTX * };
%apply long { SSLObjLoader * };
/* allow "unsigned char []" to become "byte[]" */
%include "arrays_java.i"
/* convert these pointers to use long */
%apply signed char[] {unsigned char *};
%apply signed char[] {signed char *};
/* allow ssl_get_session_id() to return "byte[]" */
%typemap(out) unsigned char * ssl_get_session_id \"if (result) jresult = SWIG_JavaArrayOutSchar(jenv, result, ssl_get_session_id_size((SSL const *)arg1));\"
/* allow ssl_client_new() to have a null session_id input */
%typemap(in) const signed char session_id[] (jbyte *jarr) {
if (jarg3 == NULL)
{
jresult = (jint)ssl_client_new(arg1,arg2,NULL,0);
return jresult;
}
if (!SWIG_JavaArrayInSchar(jenv, &jarr, &arg3, jarg3)) return 0;
}
/* Lot's of work required for an ssl_read() due to its various custom
* requirements.
*/
%native (ssl_read) int ssl_read(SSL *ssl, jobject in_data);
%{
JNIEXPORT jint JNICALL Java_axTLSj_axtlsjJNI_ssl_1read(JNIEnv *jenv, jclass jcls, jint jarg1, jobject jarg2) {
jint jresult = 0 ;
SSL *arg1;
unsigned char *arg2;
jbyte *jarr;
int result;
JNIEnv e = *jenv;
jclass holder_class;
jfieldID fid;
arg1 = (SSL *)jarg1;
result = (int)ssl_read(arg1, &arg2);
/* find the "m_buf" entry in the SSLReadHolder class */
if (!(holder_class = e->GetObjectClass(jenv,jarg2)) ||
!(fid = e->GetFieldID(jenv,holder_class, "m_buf", "[B")))
return SSL_NOT_OK;
if (result > SSL_OK)
{
int i;
/* create a new byte array to hold the read data */
jbyteArray jarray = e->NewByteArray(jenv, result);
/* copy the bytes across to the java byte array */
jarr = e->GetByteArrayElements(jenv, jarray, 0);
for (i = 0; i < result; i++)
jarr[i] = (jbyte)arg2[i];
/* clean up and set the new m_buf object */
e->ReleaseByteArrayElements(jenv, jarray, jarr, 0);
e->SetObjectField(jenv, jarg2, fid, jarray);
}
else /* set to null */
e->SetObjectField(jenv, jarg2, fid, NULL);
jresult = (jint)result;
return jresult;
}
%}
/* Big hack to get hold of a socket's file descriptor */
%typemap (jtype) long "Object"
%typemap (jstype) long "Object"
%native (getFd) int getFd(long sock);
%{
JNIEXPORT jint JNICALL Java_axTLSj_axtlsjJNI_getFd(JNIEnv *env, jclass jcls, jobject sock)
{
JNIEnv e = *env;
jfieldID fid;
jobject impl;
jobject fdesc;
/* get the SocketImpl from the Socket */
if (!(jcls = e->GetObjectClass(env,sock)) ||
!(fid = e->GetFieldID(env,jcls,"impl","Ljava/net/SocketImpl;")) ||
!(impl = e->GetObjectField(env,sock,fid))) return -1;
/* get the FileDescriptor from the SocketImpl */
if (!(jcls = e->GetObjectClass(env,impl)) ||
!(fid = e->GetFieldID(env,jcls,"fd","Ljava/io/FileDescriptor;")) ||
!(fdesc = e->GetObjectField(env,impl,fid))) return -1;
/* get the fd from the FileDescriptor */
if (!(jcls = e->GetObjectClass(env,fdesc)) ||
!(fid = e->GetFieldID(env,jcls,"fd","I"))) return -1;
/* return the descriptor */
return e->GetIntField(env,fdesc,fid);
}
%}
#endif
/* Some SWIG magic to make the API a bit more Perl friendly */
#ifdef SWIGPERL
/* for ssl_session_id() */
%typemap(out) const unsigned char * {
SV *svs = newSVpv((unsigned char *)\$1, ssl_get_session_id_size((SSL const *)arg1));
\$result = newRV(svs);
sv_2mortal(\$result);
argvi++;
}
/* for ssl_write() */
%typemap(in) const unsigned char out_data[] {
SV* tempsv;
if (!SvROK(\$input))
croak("Argument \$argnum is not a reference.");
tempsv = SvRV(\$input);
if (SvTYPE(tempsv) != SVt_PV)
croak("Argument \$argnum is not an string.");
\$1 = (unsigned char *)SvPV(tempsv, PL_na);
}
/* for ssl_read() */
%typemap(in) unsigned char **in_data (unsigned char *buf) {
\$1 = &buf;
}
%typemap(argout) unsigned char **in_data {
if (result > SSL_OK) {
SV *svs = newSVpv(*\$1, result);
\$result = newRV(svs);
sv_2mortal(\$result);
argvi++;
}
}
/* for ssl_client_new() */
%typemap(in) const unsigned char session_id[] {
/* check for a reference */
if (SvOK(\$input) && SvROK(\$input)) {
SV* tempsv = SvRV(\$input);
if (SvTYPE(tempsv) != SVt_PV)
croak("Argument \$argnum is not an string.");
\$1 = (unsigned char *)SvPV(tempsv, PL_na);
}
else
\$1 = NULL;
}
#endif
/* Some SWIG magic to make the API a bit more Lua friendly */
#ifdef SWIGLUA
SWIG_NUMBER_TYPEMAP(unsigned char);
SWIG_TYPEMAP_NUM_ARR(uchar,unsigned char);
/* for ssl_session_id() */
%typemap(out) const unsigned char * {
int i;
lua_newtable(L);
for (i = 0; i < ssl_get_session_id_size((SSL const *)arg1); i++){
lua_pushnumber(L,(lua_Number)result[i]);
lua_rawseti(L,-2,i+1); /* -1 is the number, -2 is the table */
}
SWIG_arg++;
}
/* for ssl_read() */
%typemap(in) unsigned char **in_data (unsigned char *buf) {
\$1 = &buf;
}
%typemap(argout) unsigned char **in_data {
if (result > SSL_OK) {
int i;
lua_newtable(L);
for (i = 0; i < result; i++){
lua_pushnumber(L,(lua_Number)buf2[i]);
lua_rawseti(L,-2,i+1); /* -1 is the number, -2 is the table */
}
SWIG_arg++;
}
}
/* for ssl_client_new() */
%typemap(in) const unsigned char session_id[] {
if (lua_isnil(L,\$input))
\$1 = NULL;
else
\$1 = SWIG_get_uchar_num_array_fixed(L,\$input, ssl_get_session_id((SSL const *)\$1));
}
#endif
END
# Initialise loop variables
$skip = 1;
$splitLine = 0;
parseFile(@raw_data);
close(DATA_IN);
close(DATA_OUT);
#===============================================================

137
bindings/java/SSL.java Normal file
View File

@@ -0,0 +1,137 @@
/*
* Copyright (c) 2007-2016, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* A wrapper around the unmanaged interface to give a semi-decent Java API
*/
package axTLSj;
import java.io.*;
import java.util.*;
/**
* @defgroup java_api Java API.
*
* Ensure that the appropriate dispose() methods are called when finished with
* various objects - otherwise memory leaks will result.
*/
/**
* @class SSL
* @ingroup java_api
* @brief A representation of an SSL connection.
*
*/
public class SSL
{
public int m_ssl; /**< A pointer to the real SSL type */
/**
* @brief Store the reference to an SSL context.
* @param ip [in] A reference to an SSL object.
*/
public SSL(int ip)
{
m_ssl = ip;
}
/**
* @brief Free any used resources on this connection.
*
* A "Close Notify" message is sent on this connection (if possible). It
* is up to the application to close the socket.
*/
public void dispose()
{
axtlsj.ssl_free(m_ssl);
}
/**
* @brief Return the result of a handshake.
* @return SSL_OK if the handshake is complete and ok.
* @see ssl.h for the error code list.
*/
public int handshakeStatus()
{
return axtlsj.ssl_handshake_status(m_ssl);
}
/**
* @brief Return the SSL cipher id.
* @return The cipher id which is one of:
* - SSL_AES128_SHA (0x2f)
* - SSL_AES256_SHA (0x35)
* - SSL_AES128_SHA256 (0x3c)
* - SSL_AES256_SHA256 (0x3d)
*/
public byte getCipherId()
{
return axtlsj.ssl_get_cipher_id(m_ssl);
}
/**
* @brief Get the session id for a handshake.
*
* This will be a 32 byte sequence and is available after the first
* handshaking messages are sent.
* @return The session id as a 32 byte sequence.
* @note A SSLv23 handshake may have only 16 valid bytes.
*/
public byte[] getSessionId()
{
return axtlsj.ssl_get_session_id(m_ssl);
}
/**
* @brief Retrieve an X.509 distinguished name component.
*
* When a handshake is complete and a certificate has been exchanged,
* then the details of the remote certificate can be retrieved.
*
* This will usually be used by a client to check that the server's common
* name matches the URL.
*
* A full handshake needs to occur for this call to work.
*
* @param component [in] one of:
* - SSL_X509_CERT_COMMON_NAME
* - SSL_X509_CERT_ORGANIZATION
* - SSL_X509_CERT_ORGANIZATIONAL_NAME
* - SSL_X509_CA_CERT_COMMON_NAME
* - SSL_X509_CA_CERT_ORGANIZATION
* - SSL_X509_CA_CERT_ORGANIZATIONAL_NAME
* @return The appropriate string (or null if not defined)
*/
public String getCertificateDN(int component)
{
return axtlsj.ssl_get_cert_dn(m_ssl, component);
}
}