Documentation  |   Table of Contents   |  < Previous   |  Next >   |  Index

8    Secure Sockets Layer (SSL)

Palm OS® Programmer's Companion

Volume II Communications

SSL Library Architecture ^TOP^

The SslLib library is an implementation of the SSL protocol for use under Palm OS. The API implements an interface that can be used to perform SSL and non-SSL network I/O. Figure 8.1 is intended to help show the relationship between the different components of SslLib and how they interact with the user's application.

Figure 8.1  SSL Library architecture

In this diagram, the following items are labeled.

  • Application – This is the user's application that will be using the SslLib library to secure its network connections.
  • NetLib API – This is the Palm OS Net Library API. This box represents calls into that library.
  • SslLib API – This is the Palm OS SslLib API. This box represents calls into that library via it's public interfaces.
  • SSL – The SSL protocol which is under the SslLib API. This represents the code that performs the SSL encapsulation of the application's data.
  • Handshake – The SSL protocol, during the initial connection, performs a message exchange with the remote SSL server. This box represents the part of the SSL protocol that implements this exchange.
  • Certificate Verification – As part of the SSL handshake, certificates need to be verified. This box represents the logic that performs the certificate verification.
  • Read/Write Records – The SSL protocol sends and receives SSL records. This box represents the data structures used to keep track of the last record read and the next record to be written.
  • Read/Write Buffers – SslLib buffers incoming and outgoing data. This box represents the data structures used to hold this data.
  • IO Interface – This is the code that sends data from a write buffer to the network, or the code that reads data from the network and puts it in the read buffer.

The application will call NetLib directly to configure and establish a network connection (a NetSocketRef). Once the NetSocketRef has been configured, it is passed into SslLib by associating the socket with an SslContext (SslContextSet_Socket()). When a read or write call is made to SslLib, depending on the mode of operation the SslContext is configured to operate in (SslContextSet_Mode()), either the data bytes will be directly sent, or they will under go SSL processing to encrypt and MAC the data. The diagram shows how the data bytes always go via the SslContext's read/write buffers. These buffers are used to store bytes waiting to be sent to NetLib and any extra bytes read from NetLib that have not yet been processed. The SSL protocol initially enters a handshake state, where the security parameters to use to encrypt and MAC the application's data bytes are determined. As part of this process, some certificates need to be verified.

The callback arrows indicate where the application can register to receive notification of activity in those relevant subsystems. The IO Interface can return via the info callback (SslContextSet_InfoCallback()) information about the calls to NetLib. The SSL box callback indicates the notification of SSL Protocol Alerts that are received (via the info callback). The handshake callback arrow indicates the calls to the info callback when-ever the SSL handshake protocol changes state (SslContextGet_HsState()). The information returned from these three access points is mostly of interest for debugging reasons. The final callback, the Verify callback (SslContextSet_VerifyCallback()) is often used to modify the policies regarding certificates.

Attributes ^TOP^

The SslLib library uses two main structures to hold information: the SslLib structure and the SslContext. The SslContext is used to hold all information associated with a single SSL network connection. It contains various flags that govern how the SSL protocol will operate, and also contains a read buffer and a write buffer where SSL protocol packets are assembled and disassembled. As part of the SSL handshake, various structures are created . These include the security parameters associated with the particular connection and the certificate from the SSL server that is on the other end of the network connection. Quite a large number of these attributes can be retrieved for debugging and informational reasons. Others can be set by the application to modify the behavior of the SSL protocol. The SslLib can be though of as a template for many of these options. The SslLib can have many of its attributes set, and then when an SslContext is created using the SslLib, these attributes are inherited directly. These values are copied into the SslContext, so subsequent changes to the SslLib's attributes will not modify any existing SslContext's.

Attribututes can be broken into two main classes; integer values, and pointer values. The integer values are numbers that can be set or retrieved via the SslLibGetLong(), SslLibSetLong(), SslContextGetLong() and SslContextSetLong() calls. These functions are not normally called directly; instead, applications typically employ those macros declared in SslLibMac.h. The pointer-based attributes are similarly set or retrieved using macros; those macros evaluate to calls to SslLibGetPtr(), SslLibSetPtr(), SslContextGetPtr() and SslContextSetPtr(). Whenever an attribute is passed in via a pointer, the type of the pointer is defined by the attribute being used. The object that the pointer is pointing to is always copied into the SslLib or SslContext, so the data element that is passed in does not need to be preserved. There are some exceptions to this rule. Pointer-based attributes that are retrived from an SslLib or an SslContext will always be references to objects held inside the SslLib or SslContext. If the application wishes these values to be preserved, it should copy them into local storage.

The attributes can be grouped into several categories: some will always be used, some will be regularly used and will profoundly modify the behavior of some of SslLib core functions. Some are to help debugging, and some are used to configure more subtle protocol specific internal configuration parameters. The following sections detail each attribute, grouping them by these categories.

Always-Used Attributes ^TOP^

AutoFlush

This attribute affects the behavior of SslSend() and SslWrite(). When enabled, these functions will attempt to immediately send the supplied data bytes to the network. If the application performs 200 one-byte SslWrite() calls, this will generate 200 network packets, each about 80 bytes in size (assuming TCP over Ethernet), for a total of 16,000 bytes. If this data was buffered, it would have been sent in a single packet of about 280 bytes. When buffering, there is an additional advantage in that the write calls will not generate errors unless the buffer fills. This can be used to simplify routines that package data for transmission. It is very important to remember to use the SslFlush() call when AutoFlush is disabled. SslFlush() will write any data that is in the SslContext's write buffer. If an application does not flush this data to the network, the server application at the other end will not reply, so the application will probably deadlock, awaiting a response from the server that will never come because the client has not yet sent its data to the server.

The internal logic in SslLib is as follows:


Int32 SslWrite(...) { 
write_data_to_output_buffer(...); 
if (ssl->autoflush) 
   flush_output_buffer(...); 
} 

Auto-flush is enabled by default.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_AutoFlush()
SslLib Write
SslLibSet_AutoFlush()
SslContext Read
SslContextGet_AutoFlush()
SslContext Write
SslContextSet_AutoFlush()

CipherSuites

This attribute is used to specify the SSL cipher suites that the SSL protocol will attempt to use. The pointer refers to an array of UInt8 bytes that specify the SSLv3 cipher suite values, in the order desired, to be sent to the SSL Server. The first two bytes, in network byte order, contain the number of bytes that follow. Following these two bytes are values selected from "Cipher Suites." Note that each sslCs_RSA... #define is two bytes long.

This value is inherited from the SslLib when an SslContext is created. Setting CipherSuites with a value of NULL will restore the use of the default cipher suite list. The default cipher suites list (including the size bytes) is:


{0x00, 0x08, sslCs_RSA_RC4_128_MD5, sslCs_RSA_RC4_128_SHA1, 
sslCs_RSA_RC4_56_SHA1, sslCs_RSA_RC4_40_MD5} 

To ensure that an application only uses strong encryption, it should make the following call:


static UInt8 cipherSuites[]={ 
   0x00,0x04,      /* Number of following bytes  
                      (each value is two bytes) */ 
   sslCs_RSA_RC4_128_MD5, 
   sslCs_RSA_RC4_128_SHA1 
}; 
 
SslLibSet_CipherSuites(theLibRef, lib, cipherSuites); 
/* To change the cipher suite for an existing SslContext */ 
SslContextSet_CipherSuites(theLibRef, lib, cipherSuites); 

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_CipherSuites()
SslLib Write
SslLibSet_CipherSuites()
SslContext Read
SslContextGet_CipherSuites()
SslContext Write
SslContextSet_CipherSuites()

Error

When a fatal error occurs while using an SslContext, the internal error attribute is set to the error value. The application can retrieve this error value and change it if it desires. Normally an application will not change this value, but once the error attribute is set, the SslLib network APIs will continue to return this error (unless the error is a non-fatal error) until either an SSL Reset is performed on the SslContext or the error is cleared, at which point the Error attribute will be zero. A SSL Reset can be performed with SslContextSet_Mode():


	SslContextSet_Mode(theLibRef, ssl,SslContextGet_Mode(ssl)); 

Note that SslErrIo is a non-fatal error.

Use the following macros to read and write this attribute:

SslContext Read
SslContextGet_Error()
SslContext Write
SslContextSet_Error()

Mode

This attribute is used to turn the SSL protocol on or off. It applies to the SslContext, and when set to sslModeClear, causes the SSL protocol to be bypassed. This can be useful for an application since it can be written to use the SslLib API, and still perform normal non-SSL data transfers via that API. This will let an application take advantage of the buffering provided in an SslContext so that it can perform buffer reads and buffer writes to the network. When an SslContext has its Mode attribute changed, an SSL Reset occurs. This clears any SSL state information and sets the SslContext back to a state ready to establish a new SSL connection. The SSL Session information is not cleared. This means that an application can start in sslModeClear, and then switch to sslModeSslClient. If the application switches back to sslModeClear, and again over to sslModeSslClient, a new handshake will be performed.

The SslModeSsl is a subset value of sslModeSslClient. In a future release of SslLib, the server side of the SSL protocol may be supported in which case sslModeSslServer would be added.

An application can do the following in order to determine if the SSL protocol is being used:


If (SslContextGet_Mode(theLibRef, ssl) & sslModeSsl) 
   /* SSL protocol enabled */ 
else 
   /* Using cleartext */ 

A comparison with sslModeSslClient could be used to determine if the client or server side of the protocol is being used for that particular SslContext.

The sslModeFlush flag is special. When supplied to SslContextSet_Mode(), it causes any data in the internal data buffers to be cleared. This is normally required when reusing an SslContext for a new connection. If an application is using an SslContext for cleartext, and then wants to enable SSL on the same connection, this flag should not be used.

By default, the mode attribute is set to sslModeSslClient.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_Mode()
SslLib Write
SslLibSet_Mode()
SslContext Read
SslContextGet_Mode()
SslContext Write
SslContextSet_Mode()

"Mode Attribute Values" lists the values that this attribute can have.

RbufSize

The read and write buffers are used in the SslContext to buffer incoming and outgoing data. When these values are set for an SslLib, SslContexts that are created against the SslLib will inherit the SslLib's values.

The write buffer size is the maximum number of bytes that can be buffered before a network write operation is performed. The number of application data bytes that can be buffered is less than this number when in SSL mode—approximately 30 bytes less due to SSL record overheads. If the application writes a 16 kb block of data and the write buffer is about 1 kb in size, about 16 network packets will be sent.

The read buffer is a little different from the write buffer in that it may be automatically increased is size depending on other configuration information. The SSLv3 protocol supports SSL Records up to 16 Kbytes in size. Depending on the encryption cipher being used, the protocol may need to decrypt the record in a single operation. In this case the read buffer will be increased in size to buffer the incoming record. See the ReadStreaming option for advanced usage of the read buffer to decrease latency of data availability for the application.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_RbufSize()
SslLib Write
SslLibSet_RbufSize()
SslContext Read
SslContextGet_RbufSize()
SslContext Write
SslContextSet_RbufSize()

The read buffer's default size is 2048 bytes. You can change the size of the read buffer to any value from 0 to 16384 bytes.

Socket

This call is used to specify the NetLib socket that the SslContext should use to perform its network I/O operations. An SslContext is unable to perform any network operation until the application creates and supplies a suitable NetSocketRef. The SslLib library does not perform any NetLib operations on the supplied NetSocketRef other than NetLibSend() and NetLibReceive(). All socket creation and shutdown operations must be performed by the application.

Use the following macros to read and write this attribute:

SslContext Read
SslContextGet_Socket()
SslContext Write
SslContextSet_Socket()

VerifyCallback

The callback function is used to assist with certificate verification. See SslCallbackFunc() (documented) for more details on the SslCallback structure and its usages, specifically when used to assist in certificate verification.

When a new Verify callback is specified, the application passes in a pointer to an SslCallback structure. This structure is copied into an internal SslCallback structure. The callback and data fields are preserved. When the Verify callback structure is copied into an SslLib, or copied into an SslContext, the callback function is called with a command of sslCmdNew. When the parent SslLib or SslContext is destroyed, a sslCmdFree command is issued.. If a SSL Reset is performed, a sslCmdReset command is issued. Outside of these situations, the callback will be called during the certificate verification process as outlined in the documentation for the SslCallbackFunc() function.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_VerifyCallback()
SslLib Write
SslLibSet_VerifyCallback()
SslContext Read
SslContextGet_VerifyCallback()
SslContext Write
SslContextSet_VerifyCallback()

WbufSize

The read and write buffers are used in the SslContext to buffer incoming and outgoing data. When these values are set for an SslLib, SslContexts that are created against the SslLib will inherit the SslLib's values.

The write buffer size is the maximum number of bytes that can be buffered before a network write operation is performed. The number of application data bytes that can be buffered is less than this number when in SSL mode—approximately 30 bytes less due to SSL record overheads. If the application writes a 16 kb block of data and the write buffer is about 1 kb in size, about 16 network packets will be sent.

The read buffer is a little different from the write buffer in that it may be automatically increased is size depending on other configuration information. The SSLv3 protocol supports SSL Records up to 16 Kbytes in size. Depending on the encryption cipher being used, the protocol may need to decrypt the record in a single operation. In this case the read buffer will be increased in size to buffer the incoming record. See the ReadStreaming option for advanced usage of the read buffer to decrease latency of data availability for the application.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_WbufSize()
SslLib Write
SslLibSet_WbufSize()
SslContext Read
SslContextGet_WbufSize()
SslContext Write
SslContextSet_WbufSize()

The write buffer's default size is 1024 bytes. You can change the size of the write buffer to any value from 0 to 16384 bytes.

Debugging and Informational Attributes ^TOP^

AppInt32

The AppInt32 attribute is a 32-bit integer value that the application can read or write as it sees fit. It is present so the application can attach an arbitrary value to an SslLib or a SslContext. SslLibDestroy() and SslContextDestroy() do not modify this attribute, so if the data pointed to by this attribute needs to be disposed of, the application must do this itself.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_AppInt32()
SslLib Write
SslLibGet_AppInt32()
SslContext Read
SslContextGet_AppInt32()
SslContext Write
SslContextSet_AppInt32()

AppPtr

The AppPtr attribute is a pointer value that the application can read or write as it sees fit. It is present so the application can attach an arbitrary pointer to an SslLib or a SslContext. SslLibDestroy() and SslContextDestroy() do not modify this attribute, so if the data pointed to by this attribute needs to be disposed of, the application must do this itself. The value of the AppPtr attribute is NULL by default.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_AppPtr()
SslLib Write
SslLibGet_AppPtr()
SslContext Read
SslContextGet_AppPtr()
SslContext Write
SslContextSet_AppPtr()

CipherSuite

Pass a pointer to a uint8_t pointer in order to retrieve this attribute. The returned value points to two bytes which identify the cipher suite being used by the current connection. Possible values for the cipher suites are:

0x00, 0x00
No cipher suite
0x00, 0x04
sslCs_RSA_RC4_128_MD5
0x00, 0x05
sslCs_RSA_RC4_128_SHA1
0x00, 0x64
sslCs_RSA_RC4_56_SHA1
0x00, 0x03
sslCs_RSA_RC4_40_MD5

Also see the CipherSuites attribute for instructions on specifying which cipher suites SslLib should advertise as available for use when it initially connects to the SSL server.

Use the following macro to read this attribute:

SslContext Read
SslContextGet_CipherSuite()

CipherSuiteInfo

This function differs from most others in that the application passes in a structure to be populated from the SslContext. Normally the SslContext returns a pointer to an internal data structure. This call returns the information relevant to the current cipher suite.

Use the following macro to read this attribute:

SslContext Read
SslContextGet_CipherSuiteInfo()

ClientCertRequest

The SSL protocol allows the SSL server to request a certificate from the client. This attribute will be set if the server requested a client certificate.

SslContext Read
SslContextGet_ClientCertRequest()

Compat

Turn on compatibility with incorrect SSL protocol implementations. These bugs will not normally be encountered while using the SSL protocol, but if desired, it is worth enabling the compatibility in case old buggy servers are being accessed.

See "Compatibility Flags" for the defined constants that correspond to the compatibility flags. By default, none of these compatibility flags are set.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_Compat()
SslLib Write
SslLibSet_Compat()
SslContext Read
SslContextGet_Compat()
SslContext Write
SslContextSet_Compat()

HsState

This attribute is the state that the SSL protocol is currently in. Possible values are defined under "SSL Protocol States." This information is generally only of use during debugging. See the SSL protocol specification for clarification on what the values mean.

Use the following macro to read this attribute:

SslContext Read
SslContextGet_HsState()

InfoCallback

This callback is called when various situations occur during the usage of an SslContext. It is primarily intended for debugging and feedback purposes. If the callback returns a non-zero value, this error will be returned back out to the SslLib API. The callback will be called with a command argument of sslCmdInfo.

A single Info callback is used for notification of four different types of events. The InfoInterest attribute controls which of these events will invoke the Info callback.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_InfoCallback()
SslLib Write
SslLibSet_InfoCallback()
SslContext Read
SslContextGet_InfoCallback()
SslContext Write
SslContextSet_InfoCallback()

InfoInterest

This value is used to specify the events for which the InfoCallback will be called. The value is the logical ORing of the sslFlgInfo... values listed under "InfoInterest Values." The sslFlgInfoIo value controls the notification of the four different Info Callbacks. By default, the InfoInterest attribute value is zero.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_InfoInterest()
SslLib Write
SslLibSet_InfoInterest()
SslContext Read
SslContextGet_InfoInterest()
SslContext Write
SslContextSet_InfoInterest()

IoFlags

Since we will normally be using TCP connections with SSL, this attribute is more included for completeness rather than utility. Read about this flags value in the NetLibSend() and NetLibReceive() documentation.


NOTE: The netIOFlagOutOfBand and netIOFlagPeek values are not valid and will be silently removed.

Use the following macros to read and write this attribute:

SslContext Read
SslContextGet_IoFlags()
SslContext Write
SslContextSet_IoFlags()

IoStruct

The SslContext's internal SslSocket structure.

Use the following macros to read and write this attribute:

SslContext Read
SslContextGet_IoStruct()
SslContext Write
SslContextSet_IoStruct()

IoTimeout

The SslContext contains internally a default timeout value to pass to NetLib calls. When a call is made into the SslLib API which does not specify a timeout, this internal value is used. If the API call has a timeout value, it overrides this internal value.

By default, the SslContext's internal timeout value is 10 seconds.

Use the following macros to read and write this attribute:

SslContext Read
SslContextGet_IoTimeout()
SslContext Write
SslContextSet_IoTimeout()

LastAlert

The alert values are received from the server and are either fatal or non-fatal. Non-fatal alerts have a value of the form 0x01XX, while fatal alerts have the form 0x02XX. SslLib will fail on fatal alerts and continue on non-fatal alerts. See "SSL Server Alerts" for the complete list of alerts.

Use the following macro to read this attribute:

SslContext Read
SslContextGet_LastAlert()

LastApi

This attribute is the last SslLib API call that was made. sslLastApiRead is set if SslRead(), SslPeek() or SslReceive() was called. sslLastApiWrite is set if SslWrite() or SslSend() was called. This attribute can be useful in event driven programs.

See "LastApi Attribute Values" for the set of values that this attribute can have.

Use the following macro to read this attribute:

SslContext Read
SslContextGet_LastApi()

LastIo

This function can be called to determine the last network operation. If SslLib, while performing a network operation, encounters an error, the error value will be returned to the application. Since most of the SslLib API I/O functions can cause an SSL handshake to be performed, it is often not possible to know if the reason that a SslSend() returned netErrWouldBlock is because the send operation failed or a receive operation failed (because a SSL Handshake was being performed). This attribute allows the application to determine which I/O operation was being called if an network error is returned. If the application is using NetLibSelect(), this attribute is very important. This attribute returns the last network operation performed. This means that sslLastIoNone will only be returned if the SslContext has not performed any I/O operations since its last reset.

See "LastIO Attribute Values" for the set of values that this attribute can have.

Use the following macro to read this attribute:

SslContext Read
SslContextGet_LastIo()

PeerCert

If the certificate supplied by the other end of the SSL connection is available, the certificate is returned. The returned pointer references a data structure which is internal to the SslContext and will be disposed of by the SslContext. If a new connection is established with the SslContext, previously returned PeerCert pointers will become invalid. If the application wishes to preserve the certificate for an extended period, it should make a local copy.

The SslExtendedItems structure is described in "The SslExtendedItems Structure."

Use the following macro to read this attribute:

SslContext Read
SslContextGet_PeerCert()

PeerCommonName

This call will return a pointer to an SslExtendedItems structure which contains the common name for the server's certificate. If using SSL in an https context, the client application should ensure that the common name contained in the servers certificate matches the URL requested. This function facilitates this functionality. The pointer returned refers to a data structure from inside the peer certificate; the offset field in the returned value is relative to the value returned by SslContextGet_PeerCert().

The following code shows how to access the common name from within the SslExtendedItems structure (see "The SslExtendedItems Structure" for a description of this structure):


SslExtendedItems *cert; 
SslExtendedItem *commonName; 
uint16_t length; 
uint8_t *bytes; 
 
SslContextGet_PeerCert(theLibRef, ssl, &cert); 
if (cert == NULL) goto err; 
SslContextGet_PeerCommonName(theLibRef, ssl,&commonName); 
length=commonName->len; 
bytes=((Int8 *)cert)+commonName->offset; 
// bytes now points to the common name, and length contains 
// the length of the common name string. 

Use the following macro to read this attribute:

SslContext Read
SslContextGet_PeerCommonName()

ProtocolVersion

The version of the SSL protocol to use. There are 3 versions of the SSL protocol. SSLv2 which is deprecated due to security flaws, SSLv3 which is the most widely deployed, and TLSv1, or SSLv3.1. SslLib implements only SSLv3 at this point in time, so modification of this value is not a good idea. By default this attribute is set to sslVersionSSLv3.

See "Protocol Versions" for the defined constants that correspond to the SSL protocol versions.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_ProtocolVersion()
SslLib Write
SslLibSet_ProtocolVersion()
SslContext Read
SslContextGet_ProtocolVersion()
SslContext Write
SslContextSet_ProtocolVersion()

SessionReused

The SSL protocol has the capability to re-establish a secure connection with a truncated handshake. This can be performed if both end-points have communicated previously and share an SSL Session. An SSL Session is a collection of security attributes that are normally determined as part of the SSL Handshake. If the SSL handshake was able to perform a truncated handshake by re-using the SSL session values in the SslContext, this attribute will have a non-zero value. See the SslSession attribute.

Use the following macro to read this attribute:

SslContext Read
SslContextGet_SessionReused()

SslSession

This attribute is either the SslSession currently being used, or the SslSession for this SslContext to use to establish its next connection. The SslSession holds all the security information associated with a particular SSL connection. If an SslContext is configured to use the same SslSession as a previous connection to the same server, the SSL protocol can perform a truncated handshake that involves less network traffic and a smaller CPU load on the server.

If a new connection is performed on the SslContext, or another call is made to retrieve the SslSession, any previously returned SslSession pointers will become invalid. If the program wants to keep the SslSession for an extended period, it should make a local copy.

Use the following macros to read and write this attribute:

SslContext Read
SslContextGet_SslSession()
SslContext Write
SslContextSet_SslSession()

SslVerify

During certificate verification, an SslVerify structure (see "The SslVerify Structure" for a definition of this structure) is used in the SslContext to preserve state. The application can retrieve this structure to help it resolve any problems that SslLib may have encounterd during certificate verifcation.

When a certificate is being verified and a verification error occurs, if the application has registered a VerifyCallback the callback will be called with an argv value pointing to the SslVerify structure. If there is no callback, or if the callback still reports an error, SslLib will return the error back to the application. The application can then decide to look at the certificate verification state (by calling SslContextGet_SslVerify()) and, if it determines that the error is not fatal, clear the error and re-call the SslLib API that just returned the error.

Use the following macro to read this attribute:

SslContext Read
SslContextGet_SslVerify()

Advanced Protocol Attributes ^TOP^

The following attributes are not normally used. They give access to various internal aspects of the SSL protocol and or SslLib.

BufferedReuse

The SSL protocol is capable of performing a truncated handshake if both endpoints share an SslSession from a previous connection. The truncated handshake finishes with SslLib sending a SSL handshake message to the SSL server. If the application then sends a message, say a URL, under some network stacks a significant delay can be incurred as the TCP protocol waits for a response from the SSL server's TCP stack. This option, if enabled, will buffer the last message in an SslSession-reused handshake instead of sending it over the network. The application must send data before it tries to read any, or more to the point, it must make sure the data is flushed, ether by having AutoFlush enabled, or by explicitly calling SslFlush(). There are security implications in that a "man in the middle" attack would only be detected once the first data bytes are read from the server. This would mean an attacker could have read all the bytes in the first message sent to the server. For this reason this option should not be normally used. By default, this attribute is set to zero, disabling the buffered reuse option.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_BufferedReuse()
SslLib Write
SslLibSet_BufferedReuse()
SslContext Read
SslContextGet_BufferedReuse()
SslContext Write
SslContextSet_BufferedReuse()

DontSendShutdown

During the SSL protocol shutdown sequence, the two SSL endpoints swap shutdown messages. This can incur a time penalty since extra messages need to be exchanged over the network. If DontSendShutdown is set, then a SslClose() will not send a shutdown message to the server. If DontWaitForShutdown is set, then SslLib will not wait for a shutdown message in SslClose(). To perform a correct SSL shutdown, these options should not be on.

This attribute has a default value of zero. A non-zero value indicates that the SSL protocol should be modified.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_DontSendShutdown()
SslLib Write
SslLibSet_DontSendShutdown()
SslContext Read
SslContextGet_DontSendShutdown()
SslContext Write
SslContextSet_DontSendShutdown()

DontWaitForShutdown

During the SSL protocol shutdown sequence, the two SSL endpoints swap shutdown messages. This can incur a time penalty since extra messages need to be exchanged over the network. If DontSendShutdown is set, then a SslClose() will not send a shutdown message to the server. If DontWaitForShutdown is set, then SslLib will not wait for a shutdown message in SslClose(). To perform a correct SSL shutdown, these options should not be on.

This attribute has a default value of zero. A non-zero value indicates that the SSL protocol should be modified.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_DontWaitForShutdown()
SslLib Write
SslLibSet_DontWaitForShutdown()
SslContext Read
SslContextGet_DontWaitForShutdown()
SslContext Write
SslContextSet_DontWaitForShutdown()

ReadBufPending

This attribute is the number of data bytes that are currently buffered for reading from the SslContext. This number of bytes also include bytes used for encoding SSL records. This attribute is mostly for debugging purposes.

Use the following macro to read this attribute:

SslContext Read
SslContextGet_ReadBufPending()

ReadOutstanding

This attribute is the number of bytes in the current record that have not been read from the network. If this value is 0, then all bytes that have been read from the network have had their MAC checked. If it is not 0, then the last bytes that have been read have not had their MAC value checked yet. See the Streaming and ReadStreaming attributes to see why this value can be useful.

Use the following macro to read this attribute:

SslContext Read
SslContextGet_ReadOutstanding()

ReadRecPending

Unlike ReadBufPending, this attribute is the number of application data bytes that are buffered, awaiting the application to read. If this number of bytes is 0, then the next SslRead() or SslReceive() will cause a NetLibReceive() call.

Use the following macro to read this attribute:

SslContext Read
SslContextGet_ReadRecPending()

ReadStreaming

The SSL protocol exchanges records between its endpoints. A SSL record can contain up to 16K bytes of data. This record is encrypted and protected with a cryptographic checksum call a MAC. If the network is very low speed (300 baud modem), it can be desirable to allow data to be returned to the application from the SSL connection before the full record has been downloaded. If the ReadStreaming flag is on, this protocol modification is enabled. There are security implications behind this modification. The record MAC is used to ensure that the data bytes downloaded have not been modified. If the application has been sent a 16K record, and it is read-streaming and only processing 300 bytes at a time, those bytes could be corrupted or forged without SslLib notifiying the application of this error until the last bytes of the 16K of data is sent. This attribute can be useful if the application is displaying or saving the downloaded data and does not want to be stuck in a SslRead() for an extended period of time. Remember that if read-streaming is turned on, the data may be invalid and you will only receive notification when the last bytes are read from the record.

This attribute has a default value of zero. A non-zero value indicates that the SSL protocol should be modified.

Use the following macros to read and write this attribute:

SslLib Read
SslLibGet_ReadStreaming()
SslLib Write
SslLibSet_ReadStreaming()
SslContext Read
SslContextGet_ReadStreaming()
SslContext Write
SslContextSet_ReadStreaming()

Streaming

This attribute returns 1 if the current SslContext is doing read-streaming. Just because the ReadStreaming attribute is set, that does not mean the SslLib will use read-streaming.

Use the following macro to read this attribute:

SslContext Read
SslContextGet_Streaming()

WriteBufPending

This attribute returns the number of bytes in the SslContext's write buffer waiting to be sent to the remote machine. This value will normally be zero unless AutoFlush is disabled and/or non-blocking I/O is being used. A SslFlush() will attempt to write these bytes to the network.

Use the following macro to read this attribute:

SslContext Read
SslContextGet_WriteBufPending()

Sample Code ^TOP^

The following is a simple example that demonstrates the usage of some of the SslLib libraries functions by way of listing subroutines that could be used by an application utilizing the SSL protocol.


#include <SslLib.h> 
 
/* We will perform the initial SslLib setup.  The SslLib would be 
 * created with reasonable default values, which can be modified. 
 * Quite a few of these values are 
 * 'inherited' during SslContext creation. 
 */ 
Err InitaliseSSL(libRet) 
SslLib **libRet; 
   { 
   SslLib *lib; 
   Int16 err; 
   lnt32 lvar; 
 
   /* Create the structure */ 
   if ((err=SslLibCreate(theLibRef, &lib)) != 0) 
      return(err); 
 
   /* Make sure we use the SSL protocol by default and increase 
 * the write buffer size */ 
   SslLibSet_Mode(theLibRef, lib,sslModeSslClient); 
   SslLibSet_WbufSize(theLibRef, lib,1024*8); 
 
   *libRet=lib; 
   return(0); 
   } 
 
/* This function would be called to create an sslContext from an open socket 
 */ 
Err CreateSslConnection(SslLib *lib,NetSocketRef socket,SslContext **sslRet) 
   { 
   SslContext ssl=NULL; 
   Int16 err; 
 
   /* We first create a new SslContext. 
    * This context will inherit various internal configuration 
    * details from the SslLib. 
    */ 
   if ((err=SslContextCreate(theLibRef, lib,&ssl)) != 0) 
      return(err); 
 
   /* We now specify the socket to use for IO */ 
   SslContextSet_Socket(theLibRef, ssl,socket); 
 
   /* At this point we could specify the SSL Mode of operation to use, 
    * but since we already specified this for the SslLib, we do not 
    * need to do it again. 
    */ 
   //SslContextSet_Mode(theLibRef, ssl,sslModeSslClient); 
 
   /* For this example, we will perform the SSL handshake now. */ 
   err=SslOpen(theLibRef, ssl,0,30*SysTicksPerSecond()); 
 
   *sslRet=ssl; 
   return(Err); 
   } 
 
/* Shutdown the SSL protocol and return the socket */ 
Err CloseSslConnection(SslContext ssl,NetSocketRef *retSock) 
   { 
   NetSocketRef socket; 
   SslSession *sslSession; 
   MemHandle ssHandle; 
 
   /* We will perform a full SSL protocol shutdown.  We could have 
    * set a flag against the SslContext earlier, or even against the 
    * SslLib to specify the shutdown behavior. 
    */ 
   err=SslClose(theLibRef, ssl,0,10*SysTicksPerSecond()); 
 
   /* We have now closed the SSL protocol, but the socket is still open 
    * and the SslContext still has SslSession information that 
    * other connections to the same site may want to use. 
    * In this case we ask for a reference to the SslSession. 
    * Since this structure is variable in size, once we have a 
    * reference to it, we can duplicate it if we want to keep it. 
    */ 
   SslContextGet_SslSession(theLibRef, ssl,&sslSession); 
 
   ssHandle=MemHandleNew(sslSession->length); 
   Memcpy(MemHandleLock(ssHandle),sslSession,sslSession->length) 
   MemHandleUnlock(ssHandle); 
   /* We now have a handle to a SslSession that we can store 
    * for later use with a new connection.  We would need to store 
    * this SslSession with the relevant hostname/url information 
    * to ensure we try to reuse it on only the relevant SSL server. 
    * This mapping is application/protocol-specific (urls for https). 
    */ 
 
   /* We will return the Socket */ 
   *retSock=SslContextGet_Socket(theLibRef, ssl); 
 
   /* Throw away the SslContext structure */ 
   SslContextDestroy(theLibRef, ssl); 
   return(0); 
   } 
 
Err HTTPS_call(SslContext ssl,char *send,Uint16 len,char *reply,Uint32 *outlen) 
   { 
 
   Err err; 
   Int16 ret; 
 
   /* We will send the 'send' data, and then wait for the response */ 
   ret=SslSend(theLibRef, ssl,send,len,0,NULL,0,60*SysTicksPerSecond(),&err) 
   if (ret <= 0) goto end; 
 
   ret=SslReceive(theLibRef, ssl, reply, *outlen, 0, NULL, 0,
      60*SysTicksPerSecond(), &err); 
   if (ret < 0) goto end; 
   *outlen=ret; 
end: 
   return(err); 
   }