SSL Library Architecture
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
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
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
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.
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 0x01
XX, while fatal alerts have the form 0x02
XX. 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
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
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); }