Make SSL Connection with OpenSSL

Just starting out? Need help? Post your questions and find answers here.
Barbarossa
User
User
Posts: 47
Joined: Fri Oct 12, 2012 8:50 am

Make SSL Connection with OpenSSL

Post by Barbarossa »

Hi all,

I am trying to create a SSL connection to a secured server. I am very new to both SSL and library calls so basically I don't really know what I am doing :-).

I searched the forums but there is not much about this topic so I thought maybe we could make this a work in progress thread, build the function up as we go and end up with a working example for the community.

I have to following:
- OpenSSL package installed
- A remote server with a valid certifcate on it and which accepts connections
- A private key
I am on Windows. My PureBasic version is 5.31 (x86)

I have the following code so far:

Code: Select all

Prototype.i ProtoSSL_init()
Prototype ProtoSSL_errors()
Prototype ProtoSSL_method()
Prototype.i ProtoSSL_new(SSLmethod.i)

Structure sCTX
	; unknown
EndStructure

Procedure MakeSSLConnection()
	If OpenLibrary(#LIBRARY, "ssleay32.dll")
		SSL_init.ProtoSSL_init=GetFunction(#LIBRARY, "SSL_library_init")
		SSL_errors.ProtoSSL_errors=GetFunction(#LIBRARY, "SSL_load_error_strings")
		SSL_method.ProtoSSL_method=GetFunction(#LIBRARY, "TLSv1_client_method")
		SSL_new.ProtoSSL_new=GetFunction(#LIBRARY, "SSL_CTX_new")
		SSL_errors() ; initialize readable errormessages
		SSL_init()	 ; initialize the library
		 ; so far so good
		Define *CTX.sCTX
		*CTX=SSL_new(SSL_method)
	Else
		; TODO errorhandling
 	EndIf
EndProcedure
The library loads fine. Initialization also seem to works (returns a valid returncode when tested). Now I am on a point where I need to define a new CTX object with SSL_CTX_new. This function should return a pointer to a CTX structure but I don't know what kind of variables are in this structure.

Any help will be much appreciated!

John
infratec
Always Here
Always Here
Posts: 7586
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Make SSL Connection with OpenSSL

Post by infratec »

Hi John,

that's not easy.
You have to write a complete 'wrapper' wich also includes the structures for PB.

If you can use plink from PuTTY and call it via RunProgram().
You can search the forum for plink.

Bernd
Barbarossa
User
User
Posts: 47
Joined: Fri Oct 12, 2012 8:50 am

Re: Make SSL Connection with OpenSSL

Post by Barbarossa »

Hi Bernd,

Thanks for your reply. I was afraid this might not be an easy task :(

Alternative methods, like the one you are suggesting, are also welcome of course. I also tried something similair. Using RunProgram() to start the OpenSSL commandline tool because the command line tool itself succeeded in the connection. I was able to connect to the CommandLine tool but that is about as far as I got.

I looked at Plink. I think it requires the server to run Putty since it only communicates with that? If that is true it is of no use, since I don't have control over the sofware on the server, I just want to connect to it.

John
dman
User
User
Posts: 48
Joined: Thu Oct 01, 2009 2:10 pm

Re: Make SSL Connection with OpenSSL

Post by dman »

Hi Barbarossa,

I am working on a project at the moment (SFTP client), well... it was on hold for awhile due to work lol but
I am using LibSSH (http://www.libssh.org/). As the name suggests it allows you to connect to a remote system via SSH, v1 and v2 supported.

Definately look into using it. If you want my project I have no problems giving you the source code, you would
definately do a better job :D

[edit] : I would love the PB team to eventually include this as part of PureBasic, it would be a great addition.

This is a simple connection to the SSH server using LibSSH in PB.

Code: Select all

XIncludeFile "SSHFunctions.pb"

SSHSessionID = SSH_New()

SSH_Options_Set(SSHSessionID, #SSH_OPTIONS_HOST, "192.168.2.2")
SSH_Options_Set(SSHSessionID, #SSH_OPTIONS_PORT_STR, "22")

SSHConnectionID = SSH_Connect(SSHSessionID)
Debug "SSHConnectionID: " + SSHConnectionID

SSHAuth = SSH_UserAuth_Password(SSHSessionID, "pi", "blahblah")
Debug "SSHAuth: " + SSHAuth

SFTPSessionID   = SSH_SFTP_New(SSHSessionID)
SFTPInitSession = SSH_SFTP_Init(SFTPSessionID)

SSH_Disconnect(SSHSessionID)
SSH_Free(SSHSessionID)
Last edited by dman on Tue Dec 16, 2014 3:37 pm, edited 1 time in total.
PureBasic
infratec
Always Here
Always Here
Posts: 7586
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Make SSL Connection with OpenSSL

Post by infratec »

Hi John,

plink opens a ssh tunnel. You can connect to an ssh server with it.

For example, open a connection toi a linux server and outputs df -h:

Code: Select all

Process = RunProgram("C:\plink.exe","-l user -pw password ip-address df -h", GetCurrentDirectory(), #PB_Program_Open | #PB_Program_Read | #PB_Program_Error | #PB_Program_Write)
If Process
  While  ProgramRunning(Process)
    If AvailableProgramOutput(Process)
      Debug ReadProgramString(Process)
    EndIf
    Error$ = ReadProgramError(Process)
    If Len(Error$) > 0
      Debug Error$
    EndIf
  Wend
  ProgramExitCode(Process)
EndIf
Bernd
Barbarossa
User
User
Posts: 47
Joined: Fri Oct 12, 2012 8:50 am

Re: Make SSL Connection with OpenSSL

Post by Barbarossa »

@dman

I am not sure if SSH is the same as SSL (like I said new to this) but I am willing to give it a try.

@Bernd

I tried it but it doesn't work. There is no output. Remember I have to use a 2048 bit private key to connect so I don't think a simple username and password would work.
dman
User
User
Posts: 48
Joined: Thu Oct 01, 2009 2:10 pm

Re: Make SSL Connection with OpenSSL

Post by dman »

What are you trying to achieve? is it just file transfers?
PureBasic
Barbarossa
User
User
Posts: 47
Joined: Fri Oct 12, 2012 8:50 am

Re: Make SSL Connection with OpenSSL

Post by Barbarossa »

dman wrote:What are you trying to achieve? is it just file transfers?
Yes, just file transfers back and forth (using GET and POST commands).

It is for a webbased portal which contains confidential documents. Our office server needs to communicate with the portal to retrieve documents and also has to give documents (and other information stored in documents) back to the portal. That's why we need to use an SSL connection.
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: Make SSL Connection with OpenSSL

Post by RichAlgeni »

You can use this as a base. This code uses cryptlib

Code: Select all

EnableExplicit

#debugIn  = 1
#debugOut = 2

Global NewList programList.s()
Global NewList progVersions.s()
Global homeDrive.s = "d:"

XIncludeFile "\dev\purebasic\utilities\ssl_client64.pbi"

;****************************************************************************************
; write to the log
;****************************************************************************************

Procedure.i WriteToLog(*logtext)

    PrintN("Error!!!")
    PrintN(PeekS(*logtext))

EndProcedure

;****************************************************************************************
; write to the debugger
;****************************************************************************************

Procedure.i DebugString(*debugData, returnLength.i, *netSource, debugThis.i, returnValue.i, *sslError)

    Protected errorText.s = PeekS(*sslError)

    If errorText <> ""
        ConsoleColor(12,0)
        PrintN(errorText)
    EndIf

    If debugThis = #debugIn
        ConsoleColor(10,0)
    Else
        ConsoleColor(14,0)
    EndIf

    PrintN(PeekS(*debugData))
    ConsoleColor(15,0)

EndProcedure

;****************************************************************************************
; connect, send the get request, then read data in from the secure server
;****************************************************************************************

Procedure.i getMapData()

    Protected logText.s
    Protected retValue.i
    Protected lenghtTTS.i
    Protected *errorReturn
    Protected *serverReply
    Protected sslSession.i
    Protected bytesRecvd.i
    Protected textToSend.s
    Protected debugThis.i     = 1
    Protected serverName.s    = "maps.googleapis.com"
    Protected serverPort.i    = 443
    Protected portTimeout.i   = 100
    Protected maxAttempts.i   = 50
    Protected receiveSize.i   = 32767
    Protected errorTxSize.i   = 2047
    Protected lenServerName.i = Len(serverName)

    *errorReturn = AllocateMemory(errorTxSize)
    *serverReply = AllocateMemory(receiveSize)

; create the ssl session

    retValue = CryptCreateSession(@sslSession, #CRYPT_UNUSED, #CRYPT_SESSION_SSL)
    If retValue <> #CRYPT_OK
        logText = "getMapData() > CryptCreateSession error: " + lookupError(retValue)
        WriteToLog(@logText)
    EndIf

; add the server name

    retValue = CryptSetAttributeString(sslSession, #CRYPT_SESSINFO_SERVER_NAME, @serverName, lenServerName)
    If retValue <> #CRYPT_OK
        logText = "getMapData() > CryptSetAttributeString error: " + lookupError(retValue)
        WriteToLog(@logText)
    EndIf

; specify the Port, for SSL https, it's 443

    If retValue = #CRYPT_OK
        retValue = CryptSetAttribute(sslSession, #CRYPT_SESSINFO_SERVER_PORT, serverPort)
        If retValue <> #CRYPT_OK
            logText = "getMapData() > CryptSetAttribute error: " + lookupError(retValue)
            WriteToLog(@logText)
        EndIf
    EndIf

; activate the ssl session

    If retValue = #CRYPT_OK
        retValue = CryptSetAttribute(sslSession, #CRYPT_SESSINFO_ACTIVE, 1)
        If retValue <> #CRYPT_OK
            logText = "getMapData() > CryptSetAttribute error: " + lookupError(retValue)
            WriteToLog(@logText)
        EndIf
    EndIf

; send the GET string to server

    If retValue = #CRYPT_OK
        textToSend = "GET /maps/api/geocode/xml?address=13921+US19+N,Clearwater,FL,33764&sensor=false HTTP/1.1" + #CRLF$
        textToSend + "Accept: */*" + #CRLF$
        textToSend + "Accept-Language: en-us" + #CRLF$
        textToSend + "Host: maps.google.com" + #CRLF$
        textToSend + "Connection: Keep-Alive" + #CRLF$ + #CRLF$

        lenghtTTS  = Len(textToSend)
        retValue   = sslSendData(sslSession, *errorReturn, @textToSend, lenghtTTS, @serverName, debugThis)
        If retValue <> #CRYPT_OK
            logText = "Send GET Statement > sslSendData ERROR: " + lookupError(retValue)
            WriteToLog(@logText)
        EndIf
    EndIf

; receive response from GET command

    If retValue = #CRYPT_OK
        retValue    = sslRecvData(sslSession, *errorReturn, *serverReply, bytesRecvd, receiveSize, portTimeout, maxAttempts, @serverName, debugThis)
        If retValue <> #CRYPT_OK
            logText = "Receive GET Statement > sslRecvData ERROR: " + lookupError(retValue)
            WriteToLog(@logText)
        EndIf
    EndIf

; now end the ssl session

    If sslSession
        CryptDestroySession(sslSession)
    EndIf

EndProcedure

Define result.i

OpenConsole()

; Initialize the newtork and the crypt Library

PrintN("About to open crypt library")

result = cryptInitialize()

PrintN("Opened crypt library, about to get the map")

getMapData()

; Close the Library

CryptEnd()

Input()

CloseConsole()
Here is the included program:

Code: Select all

; ------------------------------------------------------------
; Program name: ssl_client64.pbi
; ------------------------------------------------------------

; **********************************************************************************
; initialization of crypt library variables
; **********************************************************************************

; cutdown version for SSL SMTP, 64 bit version

Declare.l cryptInit()
Declare.l cryptEnd()
Declare.l cryptSetAttribute(hCrypt.l,CryptAttType.l, value.l)
Declare.l cryptSetAttributeString(hCrypt.l, CryptAttType.l, pBuff.l, StrLen.l)
Declare.l cryptCreateSession(pSession.l, cryptUser.l, SessionType.l)
Declare.l cryptDestroySession(session.l)
Declare.l cryptCreateEnvelope(penvelope.l, cryptUser.l, FormatType.l)
Declare.l cryptDestroyEnvelope(envelope.l)
Declare.l cryptPushData(envelope.l, pBuff.l, StrLen.l,  pBytesCopied.l)
Declare.l cryptFlushData(envelope.l)
Declare.l cryptPopData(envelope.l, pBuff.l, StrLen.l, pBytesCopied.l)
Declare.s lookupError(errorCode.l)

;  /****************************************************************************
;  *                                            General Constants               *
;  ****************************************************************************/

#CRYPTLIB_VERSION               = 3330
#CRYPT_MAX_KEYSIZE              =  256 ; /* The maximum user key size - 2048 bits */
#CRYPT_MAX_IVSIZE               =   32 ; /* The maximum IV size - 256 bits */
#CRYPT_MAX_PKCSIZE              =  512 ; The maximum public-key component size - 4096 bits, and maximum component
#CRYPT_MAX_PKCSIZE_ECC          =   72 ; size FOR ECCs - 576 bits (TO HANDLE the P521 curve) */
#CRYPT_MAX_HASHSIZE             =   32 ; /* The maximum hash size - 256 bits */
#CRYPT_MAX_TEXTSIZE             =   64 ; /* The maximum size of a text string (e.g.key owner name) */
#CRYPT_USE_DEFAULT              = -100 ; A magic value indicating that the default setting
#CRYPT_UNUSED                   = -101 ; /* A magic value for unused parameters */
#CRYPT_SESSION_SSL              =   03 ; /* SSL/TLS */
#CRYPT_SESSINFO_ACTIVE          = 6001 ; /* Whether session is active */
#CRYPT_SESSINFO_SERVER_NAME     = 6008 ; /* SERVER NAME */
#CRYPT_SESSINFO_SERVER_PORT     = 6009 ; /* SERVER PORT number */

;  /****************************************************************************
;  *                                           STATUS Codes                     *
;  ****************************************************************************/

; /* Errors in function calls */

#CRYPT_OK                       =   0  ; /* No error */
#CRYPT_ERROR_PARAM1             =  -1  ; /* Bad argument, parameter 1 */
#CRYPT_ERROR_PARAM2             =  -2  ; /* Bad argument, parameter 2 */
#CRYPT_ERROR_PARAM3             =  -3  ; /* Bad argument, parameter 3 */
#CRYPT_ERROR_PARAM4             =  -4  ; /* Bad argument, parameter 4 */
#CRYPT_ERROR_PARAM5             =  -5  ; /* Bad argument, parameter 5 */
#CRYPT_ERROR_PARAM6             =  -6  ; /* Bad argument, parameter 6 */
#CRYPT_ERROR_PARAM7             =  -7  ; /* Bad argument, parameter 7 */

;/* Errors due to insufficient resources */

#CRYPT_ERROR_MEMORY             = -10  ; /* Out of memory */
#CRYPT_ERROR_NOTINITED          = -11  ; /* Data has not been initialised */
#CRYPT_ERROR_INITED             = -12  ; /* Data has already been init;d */
#CRYPT_ERROR_NOSECURE           = -13  ; /* Opn.not avail.at requested sec.level */
#CRYPT_ERROR_RANDOM             = -14  ; /* No reliable random data available */
#CRYPT_ERROR_FAILED             = -15  ; /* Operation failed */
#CRYPT_ERROR_INTERNAL           = -16  ; /* Internal consistency check failed */

;/* Security violations */

#CRYPT_ERROR_NOTAVAIL           = -20  ; /* This type of opn.not available */
#CRYPT_ERROR_PERMISSION         = -21  ; /* No permiss.TO perform this operation */
#CRYPT_ERROR_WRONGKEY           = -22  ; /* Incorrect key used to decrypt data */
#CRYPT_ERROR_INCOMPLETE         = -23  ; /* Operation incomplete/still IN progress */
#CRYPT_ERROR_COMPLETE           = -24  ; /* Operation complete/can;t Continue */
#CRYPT_ERROR_TIMEOUT            = -25  ; /* Operation timed out before completion */
#CRYPT_ERROR_INVALID            = -26  ; /* Invalid/inconsistent information */
#CRYPT_ERROR_SIGNALLED          = -27  ; /* Resource destroyed by extnl.event */

;/* High-level function errors */

#CRYPT_ERROR_OVERFLOW           = -30  ; /* Resources/space exhausted */
#CRYPT_ERROR_UNDERFLOW          = -31  ; /* Not enough data available */
#CRYPT_ERROR_BADDATA            = -32  ; /* Bad/unrecognised data format */
#CRYPT_ERROR_SIGNATURE          = -33  ; /* Signature/integrity check failed */

;/* Data access function errors */

#CRYPT_ERROR_OPEN               = -40  ; /* Cannot OPEN object */
#CRYPT_ERROR_READ               = -41  ; /* Cannot READ item from object */
#CRYPT_ERROR_WRITE              = -42  ; /* Cannot WRITE item to object */
#CRYPT_ERROR_NOTFOUND           = -43  ; /* Requested item not found in object */
#CRYPT_ERROR_DUPLICATE          = -44  ; /* Item already present in object */

;/* Data enveloping errors */

#CRYPT_ENVELOPE_RESOURCE        = -50  ; /* Need resource to proceed */

;/* User defined errors here */

#CRYPT_HTTP_ERROR               = -498 ; /* Error with HTTP protocol */
#CRYPT_SMTP_ERROR               = -499 ; /* Error with SMTP protocol */

;  /****************************************************************************
;  *                           initialization                                  *
;  ****************************************************************************/

Procedure.l cryptInitialize()

; declare the variables needed

    Global cryptLib.l               = OpenLibrary(#PB_Any, "\Utilities\cryptlib64.dll")

    Global *cryptInit               = GetFunction(cryptLib, "cryptInit")
    Global *cryptEnd                = GetFunction(cryptLib, "cryptEnd")
    Global *cryptSetAttribute       = GetFunction(cryptLib, "cryptSetAttribute")
    Global *cryptSetAttributeString = GetFunction(cryptLib, "cryptSetAttributeString")
    Global *cryptCreateSession      = GetFunction(cryptLib, "cryptCreateSession")
    Global *cryptDestroySession     = GetFunction(cryptLib, "cryptDestroySession")
    Global *cryptCreateEnvelope     = GetFunction(cryptLib, "cryptCreateEnvelope")
    Global *cryptDestroyEnvelope    = GetFunction(cryptLib, "cryptDestroyEnvelope")
    Global *cryptPushData           = GetFunction(cryptLib, "cryptPushData")
    Global *cryptFlushData          = GetFunction(cryptLib, "cryptFlushData")
    Global *cryptPopData            = GetFunction(cryptLib, "cryptPopData")

; Initialize the crypt Library

    Protected initValue.l = CryptInit()
    Protected initResult.l

    If  initValue = #CRYPT_OK
        initResult = #True
    Else
        initResult = #False
    EndIf

    ProcedureReturn initResult

EndProcedure

;****************************************************************************************
; receive data from a server encrypted by ssl
;****************************************************************************************

Procedure.l sslRecvData(secureSession.l, *sslError, *returnData, *returnLength, bufferSize.l, socketTimeout.l, maxReadTrys.l, *netSource, debugThis.l)

    Protected returnValue.l  = 0
    Protected attemptCount.l = 0

; initialize the return data

    PokeI(*returnLength, 0)
    FillMemory(*returnData, bufferSize)

; get incoming data from server, wait as needed

    Repeat
        Delay(socketTimeout)
        attemptCount = attemptCount + 1
        If attemptCount > maxReadTrys; if still nothing received, just get out
            Break
        EndIf

        returnValue = CryptPopData(secureSession, *returnData, bufferSize, *returnLength)
        If returnValue = #CRYPT_OK
            If PeekI(*returnLength) > 0
                Break
            EndIf
        Else
            PokeS(*sslError, "CryptPopData ERROR: " + lookupError(returnValue))
            Break
        EndIf
    ForEver

; send the data we have read to the debugger listing, if needed

    If debugThis
        DebugString(*returnData, PeekI(*returnLength), *netSource, #debugIn, returnValue, *sslError)
    EndIf

    ProcedureReturn returnValue

EndProcedure

;****************************************************************************************
; send data to a server encrypted by ssl
;****************************************************************************************

Procedure.l sslSendData(secureSession.l, *sslError, *sendText, lenSendText, *netSource, debugThis.l)

    Protected returnValue.l = 0
    Protected bytesSent.l   = 0

; copy data into an encrypted envelope

    returnValue = CryptPushData(secureSession, *sendText, lenSendText, @bytesSent)
    If returnValue <> #CRYPT_OK Or lenSendText <> bytesSent
        PokeS(*sslError, "CryptPushData ERROR " + lookupError(returnValue) + ", lenSend = " + Str(lenSendText) + ", bytesSent = " + Str(bytesSent))
    EndIf

; send encrypted data to server

    If returnValue = #CRYPT_OK
        returnValue = CryptFlushData(secureSession)
        If returnValue <> #CRYPT_OK
            PokeS(*sslError, "CryptFlushData ERROR " + lookupError(returnValue))
        EndIf
    EndIf

; send the result of the send to the debugger listing, if needed

    If debugThis
        DebugString(*sendText, bytesSent, *netSource, #debugOut, returnValue, *sslError)
    EndIf

    ProcedureReturn returnValue

EndProcedure

;  /****************************************************************************
;  *                                        General Functions                   *
;  ****************************************************************************/

Procedure.l cryptInit()
    ProcedureReturn CallFunctionFast(*cryptInit)
EndProcedure

Procedure.l cryptEnd()
    ProcedureReturn CallFunctionFast(*cryptEnd)
EndProcedure

Procedure.l cryptSetAttribute(hCrypt.l,CryptAttType.l, value.l)
   ProcedureReturn CallFunctionFast(*cryptSetAttribute, hCrypt.l, CryptAttType.l, value.l)
EndProcedure

Procedure.l cryptSetAttributeString(hCrypt.l, CryptAttType.l, pBuff.l, StrLen.l)
    ProcedureReturn CallFunctionFast(*cryptSetAttributeString, hCrypt.l, CryptAttType.l, pBuff.l, StrLen.l)
EndProcedure

;  /****************************************************************************
;  *                                        Envelope & Session Functions        *
;  ****************************************************************************/

Procedure.l cryptCreateSession(pSession.l, cryptUser.l, SessionType.l)
    ProcedureReturn CallFunctionFast(*cryptCreateSession, pSession.l, cryptUser.l, SessionType.l)
EndProcedure

Procedure.l cryptDestroySession(session.l)
    ProcedureReturn CallFunctionFast(*cryptDestroySession, session.l)
EndProcedure

Procedure.l cryptCreateEnvelope(penvelope.l, cryptUser.l, FormatType.l)
    ProcedureReturn CallFunctionFast(*cryptCreateEnvelope, penvelope.l, cryptUser.l, FormatType.l)
EndProcedure

Procedure.l cryptDestroyEnvelope(envelope.l)
    ProcedureReturn CallFunctionFast(*cryptDestroyEnvelope, envelope.l)
EndProcedure

Procedure.l cryptPushData(envelope.l, pBuff.l, StrLen.l,  pBytesCopied.l)
    ProcedureReturn CallFunctionFast(*cryptPushData, envelope.l, pBuff.l, StrLen.l,  pBytesCopied.l)
EndProcedure

Procedure.l cryptFlushData(envelope.l)
    ProcedureReturn CallFunctionFast(*cryptFlushData, envelope.l)
EndProcedure

Procedure.l cryptPopData(envelope.l, pBuff.l, StrLen.l, pBytesCopied.l)
    ProcedureReturn CallFunctionFast(*cryptPopData, envelope.l, pBuff.l, StrLen.l, pBytesCopied.l)
EndProcedure

;  /*****************************************************************************                                                                                                                 *
;  *                                          User Interface Functions          *
;  ****************************************************************************/

Procedure.s lookupError(errorCode.l)

    Select errorCode
    Case #CRYPT_OK
        ProcedureReturn  ""
    Case #CRYPT_ERROR_PARAM1
        ProcedureReturn  "Bad argument - parameter 1"
    Case #CRYPT_ERROR_PARAM2
        ProcedureReturn  "Bad argument - parameter 2"
    Case #CRYPT_ERROR_PARAM3
        ProcedureReturn  "Bad argument - parameter 3"
    Case #CRYPT_ERROR_PARAM4
        ProcedureReturn  "Bad argument - parameter 4"
    Case #CRYPT_ERROR_PARAM5
        ProcedureReturn  "Bad argument - parameter 5"
    Case #CRYPT_ERROR_PARAM6
        ProcedureReturn  "Bad argument - parameter 6"
    Case #CRYPT_ERROR_PARAM7
        ProcedureReturn  "Bad argument - parameter 7"
    Case #CRYPT_ERROR_MEMORY
        ProcedureReturn  "Out of memory"
    Case #CRYPT_ERROR_NOTINITED
        ProcedureReturn  "Data has not been initialized"
    Case #CRYPT_ERROR_INITED
        ProcedureReturn  "Data has already been initialized"
    Case #CRYPT_ERROR_NOSECURE
        ProcedureReturn  "Operation not available at requested security level"
    Case #CRYPT_ERROR_RANDOM
        ProcedureReturn  "No reliable random data available"
    Case #CRYPT_ERROR_FAILED
        ProcedureReturn  "Operation failed"
    Case #CRYPT_ERROR_INTERNAL
        ProcedureReturn  "Internal consistency check failed"
    Case #CRYPT_ERROR_NOTAVAIL
        ProcedureReturn  "This type of operation not available"
    Case #CRYPT_ERROR_PERMISSION
        ProcedureReturn  "No permission to perform this operation"
    Case #CRYPT_ERROR_WRONGKEY
        ProcedureReturn  "Incorrect key used to decrypt data"
    Case #CRYPT_ERROR_INCOMPLETE
        ProcedureReturn  "Operation incomplete/still in progress"
    Case #CRYPT_ERROR_COMPLETE
        ProcedureReturn  "Operation complete/can't continue"
    Case #CRYPT_ERROR_TIMEOUT
        ProcedureReturn  "Operation timed out before completion"
    Case #CRYPT_ERROR_INVALID
        ProcedureReturn  "Invalid/inconsistent information"
    Case #CRYPT_ERROR_SIGNALLED
        ProcedureReturn  "Resource destroyed by external event"
    Case #CRYPT_ERROR_OVERFLOW
        ProcedureReturn  "Resources/space exhausted"
    Case #CRYPT_ERROR_UNDERFLOW
        ProcedureReturn  "Not enough data available"
    Case #CRYPT_ERROR_BADDATA
        ProcedureReturn  "Bad/unrecognised data format"
    Case #CRYPT_ERROR_SIGNATURE
        ProcedureReturn  "Signature/integrity check failed"
    Case #CRYPT_ERROR_OPEN
        ProcedureReturn  "Cannot open object"
    Case #CRYPT_ERROR_READ
        ProcedureReturn  "Cannot read item from object"
    Case #CRYPT_ERROR_WRITE
        ProcedureReturn  "Cannot write item to object"
    Case #CRYPT_ERROR_NOTFOUND
        ProcedureReturn  "Requested item not found in object"
    Case #CRYPT_ERROR_DUPLICATE
        ProcedureReturn  "Item already present in object"
    Case #CRYPT_ENVELOPE_RESOURCE
        ProcedureReturn  "Need resource to proceed"
    Default
        ProcedureReturn  "Unknown error code: " + Str(errorCode)
    EndSelect

EndProcedure
Here is a link to the dlls

http://www.rca2.com/dlls/Cryptlibdlls.zip
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: Make SSL Connection with OpenSSL

Post by RichAlgeni »

I do believe that we need to tackle OpenSSL soon.
Barbarossa
User
User
Posts: 47
Joined: Fri Oct 12, 2012 8:50 am

Re: Make SSL Connection with OpenSSL

Post by Barbarossa »

RichAlgeni,

Thanks, I will have a look and see if I can make it work.

Question: how well tested is this piece of code?

For example I see this procedure:
Procedure.l sslRecvData(secureSession.l, *sslError, *returnData, *returnLength, bufferSize.l, socketTimeout.l, maxReadTrys.l, *netSource, debugThis.l)

Which is called upon as:
retValue = sslRecvData(sslSession, *errorReturn, *serverReply, bytesRecvd, receiveSize, portTimeout, maxAttempts, @serverName, debugThis)

John
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: Make SSL Connection with OpenSSL

Post by RichAlgeni »

It's been working fine for me in a production setting for over a year.

Try it.
Barbarossa
User
User
Posts: 47
Joined: Fri Oct 12, 2012 8:50 am

Re: Make SSL Connection with OpenSSL

Post by Barbarossa »

RichAlgeni wrote:It's been working fine for me in a production setting for over a year.

Try it.
I did and it doesn't compile because obviously a pointer is not the same as an integer.

There are some more problems. The constants for the Cryptformats are not defined. From the manual:
cryptCreateEnvelope( &cryptEnvelope, cryptUser, CRYPT_FORMAT_CRYPTLIB )

In the source it is defined as FormatType.l

Code: Select all

Procedure.l cryptCreateEnvelope(penvelope.l, cryptUser.l, FormatType.l)
This would not be a problem, but the variable FormatType never gets assigned a value in your example.
If I fix the first error your example runs (with FormatType=0) but when I try to do something else with it this becomes a problem.

Anyway I think I can probably get it to work since what you made is quite good already and this helps me understand how SSL works (the manual of CryptLib is also quite good). So I will continue to put some more effort in it. Thanks again.

@Fred the best thing would be to have an SSL Library. Like the previous poster said, I think it is time for it.

John
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: Make SSL Connection with OpenSSL

Post by RichAlgeni »

I extracted code from my routines and tried to boil it down to just what you needed, I'm really sorry I inconvenienced you in a way that made you do some work for yourself.

If only I didn't have to work for a living to provide a life for my family, I could have done a better job for you! Next time, I'll block out a whole day for you, so I can do better!

BTW, this is all I get when I run this exact code:

Code: Select all

About to open crypt library
Opened crypt library, about to get the map
GET /maps/api/geocode/xml?address=13921+US19+N,Clearwater,FL,33764&sensor=false HTTP/1.1
Accept: */*
Accept-Language: en-us
Host: maps.google.com
Connection: Keep-Alive


HTTP/1.1 200 OK
Content-Type: application/xml; charset=UTF-8
Date: Wed, 17 Dec 2014 20:22:57 GMT
Expires: Thu, 18 Dec 2014 20:22:57 GMT
Cache-Control: public, max-age=86400
Vary: Accept-Language
Access-Control-Allow-Origin: *
Server: mafe
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Alternate-Protocol: 443:quic,p=0.02
Transfer-Encoding: chunked

860
<?xml version="1.0" encoding="UTF-8"?>
<GeocodeResponse>
 <status>OK</status>
 <result>
  <type>street_address</type>
  <formatted_address>13921 US Highway 19 North, Clearwater, FL 33764, USA</formatted_address>
  <address_component>
   <long_name>13921</long_name>
   <short_name>13921</short_name>
   <type>street_number</type>
  </address_component>
  <address_component>
   <long_name>US Highway 19 North</long_name>
   <short_name>US Hwy 19 N</short_name>
   <type>route</type>
  </address_component>
  <address_component>
   <long_name>Clearwater</long_name>
   <short_name>Clearwater</short_name>
   <type>locality</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Pinellas County</long_name>
   <short_name>Pinellas County</short_name>
   <type>administrative_area_level_2</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Florida</long_name>
   <short_name>FL</short_name>
   <type>administrative_area_level_1</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>United States</long_name>
   <short_name>US</short_name>
   <type>country</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>33764</long_name>
   <short_name>33764</short_name>
   <type>postal_code</type>
  </address_component>
  <address_component>
   <long_name>7235</long_name>
   <short_name>7235</short_name>
   <type>postal_code_suffix</type>
  </address_component>
  <geometry>
   <location>
    <lat>27.8977089</lat>
    <lng>-82.7251621</lng>
   </location>
   <location_type>RANGE_INTERPOLATED</location_type>
   <viewport>
    <southwest>
     <lat>27.8963557</lat>
     <lng>-82.7265190</lng>
    </southwest>
    <northeast>
     <lat>27.8990536</lat>
     <lng>-82.7238210</lng>
    </northeast>
   </viewport>
   <bounds>
    <southwest>
     <lat>27.8977004</lat>
     <lng>-82.7251779</lng>
    </southwest>
    <northeast>
     <lat>27.8977089</lat>
     <lng>-82.7251621</lng>
    </northeast>
   </bounds>
  </geometry>
  <partial_match>true</partial_match>
 </result>
</GeocodeResponse>

0
Barbarossa
User
User
Posts: 47
Joined: Fri Oct 12, 2012 8:50 am

Re: Make SSL Connection with OpenSSL

Post by Barbarossa »

Well sorry if you are offended about my posts, that was never my intention.

Of course I am willing to the work myself. But since I don't really understand all this SSL business I want to make sure if the code is reliable. Otherwise it will be difficult for me to determine if it doesn't work because I did something wrong trying to establish the connection or the problem lies within the code.

When i fix the problems I get the same output as you. Why it doesn't work for my own server I have yet to figure out.

John
Post Reply