Protocol++® (Protocolpp®)
v5.6.2
|
#include "include/jtls.h"
For additional information see http://en.wikipedia.org/wiki/Transport_Layer_Security
The TLS protocol exchanges records—which encapsulate the data to be exchanged in a specific format (see below). Each record can be compressed, padded, appended with a message authentication code (MAC), or encrypted, all depending on the state of the connection. Each record has a content type field that designates the type of data encapsulated, a length field and a TLS version field. The data encapsulated may be control or procedural messages of the TLS itself, or simply the application data needed to be transferred by TLS. The specifications (cipher suite, keys etc.) required to exchange application data by TLS, are agreed upon in the "TLS handshake" between the client requesting the data and the server responding to requests. The protocol therefore defines both the structure of payloads transferred in TLS and the procedure to establish and monitor the transfer
TLS handshake
When the connection starts, the record encapsulates a "control" protocol—the handshake messaging protocol (content type 22). This protocol is used to exchange all the information required by both sides for the exchange of the actual application data by TLS. It defines the messages formatting or containing this information and the order of their exchange. These may vary according to the demands of the client and server—i.e., there are several possible procedures to set up the connection. This initial exchange results in a successful TLS connection (both parties ready to transfer application data with TLS) or an alert message (as specified below)
A typical connection example follows, illustrating a handshake where the server (but not the client) is authenticated by its certificate:
Client-authenticated TLS handshake
The following full example shows a client being authenticated (in addition to the server as in the example above) via TLS using certificates exchanged between both peers.
Resumed TLS handshake
Public key operations (e.g., RSA) are relatively expensive in terms of computational power. TLS provides a secure shortcut in the handshake mechanism to avoid these operations: resumed sessions. Resumed sessions are implemented using session IDs or session tickets.
Apart from the performance benefit, resumed sessions can also be used for Single sign-on, as it guarantees that both the original session and any resumed session originate from the same client. This is of particular importance for the FTP over TLS/SSL protocol, which would otherwise suffer from a man-in-the-middle attack in which an attacker could intercept the contents of the secondary data connections.[258]
Session IDs
In an ordinary full handshake, the server sends a session id as part of the ServerHello message. The client associates this session id with the server's IP address and TCP port, so that when the client connects again to that server, it can use the session id to shortcut the handshake. In the server, the session id maps to the cryptographic parameters previously negotiated, specifically the "master secret". Both sides must have the same "master secret" or the resumed handshake will fail (this prevents an eavesdropper from using a session id). The random data in the ClientHello and ServerHello messages virtually guarantee that the generated connection keys will be different from in the previous connection. In the RFCs, this type of handshake is called an abbreviated handshake. It is also described in the literature as a restart handshake.
Session tickets
RFC 5077 extends TLS via use of session tickets, instead of session IDs. It defines a way to resume a TLS session without requiring that session-specific state is stored at the TLS server. When using session tickets, the TLS server stores its session-specific state in a session ticket and sends the session ticket to the TLS client for storing. The client resumes a TLS session by sending the session ticket to the server, and the server resumes the TLS session according to the session-specific state in the ticket. The session ticket is encrypted and authenticated by the server, and the server verifies its validity before using its contents.
One particular weakness of this method with OpenSSL is that it always limits encryption and authentication security of the transmitted TLS session ticket to AES128-CBC-SHA256, no matter what other TLS parameters were negotiated for the actual TLS session.[248] This means that the state information (the TLS session ticket) is not as well protected as the TLS session itself. Of particular concern is OpenSSL's storage of the keys in an application-wide context (SSL_CTX), i.e. for the life of the application, and not allowing for re-keying of the AES128-CBC-SHA256 TLS session tickets without resetting the application-wide OpenSSL context (which is uncommon, error-prone and often requires manual administrative intervention).[249][247]
TLS Records
This is the general format for all TLS records (packets) [1]
Content Type
This field identifies the Record Layer Protocol Type contained in this Record
Hex | Dec | Type |
---|---|---|
0x14 | 20 | ChangeCipherSpec |
0x15 | 21 | Alert |
0x16 | 22 | Handshake |
0x17 | 23 | Application |
0x18 | 24 | Heartbeat |
Version
This field identifies the major and minor version of TLS for the contained message. For a ClientHello message, this need not be the highest version supported by the client
Major Version | Minor Version | Version Type |
---|---|---|
0x03 | 0x00 | SSL3.0 |
0x03 | 0x01 | TLS1.0 |
0x03 | 0x02 | TLS1.1 |
0x03 | 0x03 | TLS1.2 |
0xFF | 0xFE | DTLS |
Length
The length of Protocol message(s), MAC and Padding, not to exceed bytes (16KB)
Protocol Message(s)
One or more messages identified by the Protocol field. Note that this field may be encrypted depending on the state of the connection
MAC and Padding
A message authentication code computed over the Protocol message, with additional key material included Note that this field may be encrypted, or not included entirely, depending on the state of the connection No MAC or Padding can be present at end of TLS records before all cipher algorithms and parameters have been negotiated and handshaked and then confirmed by sending a CipherStateChange record (see below) for signaling that these parameters will take effect in all further records sent by the same peer
Handshake protocol
Most messages exchanged during the setup of the TLS session are based on this record, unless an error or warning occurs and needs to be signaled by an Alert protocol record (see below), or the encryption mode of the session is modified by another record (see ChangeCipherSpec protocol below)
+ | Byte0 | Byte1 | Byte2 | Byte3 |
---|---|---|---|---|
Byte 0 | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |||
Byte 1-4 | ||||
Byte 5..8 | Message Type | |||
Byte 9-(n-1) | ||||
Message type
This field identifies the handshake message type
Code | Description |
---|---|
0 | HelloRequest |
1 | ClientHello |
2 | ServerHello |
4 | NewSessionTicket |
11 | Certificate |
12 | ServerKeyExchange |
13 | CertificateRequest |
14 | ServerHelloDone |
15 | CertificateVerify |
16 | ClientExchange |
20 | Finished |
Handshake message data length
This is a 3-byte field indicating the length of the handshake data, not including the header Note that multiple handshake messages may be combined within one record
Alert protocol
This record should normally not be sent during normal handshaking or application exchanges. However, this message can be sent at any time during the handshake and up to the closure of the session. If this is used to signal a fatal error, the session will be closed immediately after sending this record, so this record is used to give a reason for this closure. If the alert level is flagged as a warning, the remote can decide to close the session if it decides that the session is not reliable enough for its needs (before doing so, the remote may also send its own signal)
+ | Byte0 | Byte1 | Byte2 | Byte3 |
---|---|---|---|---|
Byte 0 | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |||
Byte 1-4 | ||||
Byte 5..6 | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |||
Byte 7-(n-1) | ||||
Byte p-(q-1) |
Level
This field identifies the level of alert. If the level is fatal, the sender should close the session immediately. Otherwise, the recipient may decide to terminate the session itself, by sending its own fatal alert and closing the session itself immediately after sending it. The use of Alert records is optional, however if it is missing before the session closure, the session may be resumed automatically (with its handshakes)
Normal closure of a session after termination of the transported application should preferably be alerted with at least the Close notify Alert type (with a simple warning level) to prevent such automatic resume of a new session. Signaling explicitly the normal closure of a secure session before effectively closing its transport layer is useful to prevent or detect attacks (like attempts to truncate the securely transported data, if it intrinsically does not have a predetermined length or duration that the recipient of the secured data may expect)
ChangeCipherSpec protocol
+ | Byte0 | Byte1 | Byte2 | Byte3 |
---|---|---|---|---|
Byte 0 | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |||
Byte 1-4 | ||||
Byte 5 | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
CCS protocol type
Currently only 1
Application protocol
+ | Byte0 | Byte1 | Byte2 | Byte3 |
---|---|---|---|---|
Byte 0 | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |||
Byte 1-4 | ||||
Byte 5-(m-1) | ||||
Byte m-(p-1) | ||||
Byte p-(q-1) |
+ | Byte0 | Byte1 | Byte2 | Byte3 |
---|---|---|---|---|
Byte 0 | XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | |||
Byte 1-4 | ||||
Byte 5-8 | ||||
Byte 9-12 | ||||
Byte 13-(m-1) | ||||
Byte m-(p-1) | ||||
Byte p-(q-1) |
Length
Length of the application data (excluding the protocol header and including the MAC and padding trailers)
MAC
20 bytes for the SHA1 based HMAC, 16 bytes for the MD5 based HMAC
Padding
Variable length; last byte contains the padding length
This document describes the use of the ChaCha stream cipher and Poly1305 authenticator in version 1.2 or later of the the Transport Layer Security (TLS) [RFC5246] protocol, as well as version 1.2 or later of the Datagram Transport Layer Security (DTLS) protocol [RFC6347].
ChaCha [CHACHA] is a stream cipher developed by D.J. Bernstein in 2008. It is a refinement of Salsa20, which is one of the selected ciphers in the eSTREAM portfolio [ESTREAM], and was used as the core of the SHA-3 finalist, BLAKE.
The variant of ChaCha used in this document has 20 rounds, a 96-bit nonce and a 256-bit key, and will be referred to as ChaCha20. This is the conservative variant (with respect to security) of the ChaCha family and is described in [RFC7539].
Poly1305 [POLY1305] is a Wegman-Carter, one-time authenticator designed by D.J. Bernstein. Poly1305 takes a 256-bit, one-time key and a message, and produces a 16-byte tag that authenticates the message such that an attacker has a negligible chance of producing a valid tag for an inauthentic message. It is also described in [RFC7539].
ChaCha and Poly1305 have both been designed for high performance in software implementations. They typically admit a compact implementation that uses few resources and inexpensive operations, which makes them suitable on a wide range of architectures. They have also been designed to minimize leakage of information through side channels.
Recent attacks [CBC-ATTACK] have indicated problems with the CBC-mode cipher suites in TLS and DTLS, as well as issues with the only supported stream cipher (RC4) [RC4-ATTACK]. While the existing AEAD cipher suites (based on AES-GCM) address some of these issues, there are concerns about their performance and ease of software implementation. Therefore, a new stream cipher to replace RC4 and address all the previous issues is needed. It is the purpose of this document to describe a secure stream cipher for both TLS and DTLS that is comparable to RC4 in speed on a wide range of platforms and can be implemented easily without being vulnerable to software side-channel attacks.
ChaCha20 Cipher Suites
The ChaCha20 and Poly1305 primitives are built into an AEAD algorithm [RFC5116], AEAD_CHACHA20_POLY1305, as described in [RFC7539]. This AEAD is incorporated into TLS and DTLS as specified in section 6.2.3.3 of [RFC5246]. AEAD_CHACHA20_POLY1305 requires a 96-bit nonce, which is formed as follows:
The following cipher suites are defined.
The DHE_RSA, ECDHE_RSA, ECDHE_ECDSA, PSK, ECDHE_PSK, DHE_PSK and RSA_PSK key exchanges for these cipher suites are unaltered and thus are performed as defined in [RFC5246], [RFC4492], and [RFC5489]. The pseudorandom function (PRF) for all the cipher suites defined in this document is the TLS PRF with SHA-256 as the hash function.
IANA Considerations
IANA is requested to add the following entries in the TLS Cipher Suite Registry:
The cipher suite numbers listed in the second column are numbers used for cipher suite interoperability testing and it’s suggested that IANA use these values for assignment.
Camellia was selected as a recommended cryptographic primitive by the EU NESSIE (New European Schemes for Signatures, Integrity and Encryption) project [NESSIE] and included in the list of cryptographic techniques for Japanese e-Government systems, which were selected by the Japan CRYPTREC (Cryptography Research and Evaluation Committees) [CRYPTREC]. Camellia is also included in specification of the TV-Anytime Forum [TV-ANYTIME]. The TV-Anytime Forum is an association of organizations that seeks to develop specifications to enable audio-visual and other services based on mass-market high-volume digital storage in consumer platforms. Camellia is specified as Cipher Suite in TLS used by Phase 1 S-7 (Bi-directional Metadata Delivery Protection) specification and S-5 (TV-Anytime Rights Management and Protection Information for Broadcast Applications) specification. Camellia has been submitted to other several standardization bodies such as ISO (ISO/IEC 18033) and IETF S/MIME Mail Security Working Group [Camellia-CMS].
Camellia supports 128-bit block size and 128-, 192-, and 256-bit key sizes; i.e., the same interface specifications as the Advanced Encryption Standard (AES) [AES]. Camellia was jointly developed by NTT and Mitsubishi Electric Corporation in 2000 [CamelliaTech]. It was carefully designed to withstand all known cryptanalytic attacks and even to have a sufficiently large security leeway. It has been scrutinized by worldwide cryptographic experts.
Camellia was also designed to be suitable for both software and hardware implementations and to cover all possible encryption applications, from low-cost smart cards to high-speed network systems. Compared to the AES, Camellia offers at least comparable encryption speed in software and hardware. In addition, a distinguishing feature is its small hardware design. Camellia perfectly meets one of the current TLS market requirements, for which low power consumption is mandatory.
The algorithm specification and object identifiers are described in [Camellia-Desc]. The Camellia homepage, http://info.isl.ntt.co.jp/camellia/, contains a wealth of information about camellia, including detailed specification, security analysis, performance figures, reference implementation, and test vectors.
Proposed Cipher Suites
The new cipher suites proposed here have the following definitions:
Cipher
All the cipher suites described here use Camellia in cipher block chaining (CBC) mode as a bulk cipher algorithm. Camellia is a 128 bit block cipher with 128-, 192-, and 256-bit key sizes; i.e., it supports the same block and key sizes as the Advanced Encryption Standard (AES). However, this document only defines cipher suites for 128- and 256-bit keys as well as AES cipher suites for TLS [AES-TLS]. These cipher suites are efficient and practical enough for most uses, including high-security applications.
Cipher | Type | Key Material | Expanded Key Material | Effective Key Bits | IV Size | Block Size |
---|---|---|---|---|---|---|
CAMELLIA_128_CBC | Block | |||||
CAMELLIA_256_CBC | Block |
Hash
All the cipher suites described here use SHA-1 [SHA-1] in a Hashed Message Authentication Code (HMAC) construction, as described in section 5 of [TLS].
Key Exchange
The cipher suites defined here differ in the type of certificate and key exchange method. They use the following options:
Cipher Suite Key Exchange Algorithm
ARIA
ARIA is a general-purpose block cipher algorithm developed by Korean cryptographers in 2003. It is an iterated block cipher with 128-, 192-, and 256-bit keys and encrypts 128-bit blocks in 12, 14, and 16 rounds, depending on the key size. It is secure and suitable for most software and hardware implementations on 32-bit and 8-bit processors. It was established as a Korean standard block cipher algorithm in 2004 [ARIAKS] and has been widely used in Korea, especially for government-to-public services. It was included in PKCS #11 in 2007 [ARIAPKCS]. The algorithm specification and object identifiers are described in [RFC5794].
Proposed Cipher Suites
The first twenty cipher suites use ARIA [RFC5794] in Cipher Block Chaining (CBC) mode with a SHA-2 family Hashed Message Authentication Code (HMAC). Eight out of twenty use elliptic curves.
GCM-Based Cipher Suites
The next twenty cipher suites use the same asymmetric algorithms as those in the previous section but use the authenticated encryption modes defined in TLS 1.2 with the ARIA in Galois Counter Mode (GCM) [GCM].
PSK Cipher Suites
The next fourteen cipher suites describe PSK cipher suites. Eight cipher suites use an HMAC and six cipher suites use the ARIA Galois Counter Mode.
Cipher
The ARIA_128_CBC cipher suites use ARIA [RFC5794] in CBC mode with a 128-bit key and 128-bit Initialization Vector (IV); the ARIA_256_CBC cipher suites use a 256-bit key and 128-bit IV. AES-authenticated encryption with additional data algorithms, AEAD_AES_128_GCM, and AEAD_AES_256_GCM are described in [RFC5116]. AES GCM cipher suites for TLS are described in [RFC5288]. AES and ARIA share common characteristics, including key sizes and block length. ARIA_128_GCM and ARIA_256_GCM are defined according to those characteristics of AES.
IANA Considerations
IANA has allocated the following numbers in the TLS Cipher Suite Registry:
SEED is a symmetric encryption algorithm that was developed by Korea Information Security Agency (KISA) and a group of experts, beginning in 1998. The input/output block size of SEED is 128-bit and the key length is also 128-bit. SEED has the 16-round Feistel structure. A 128-bit input is divided into two 64-bit blocks and the right 64-bit block is an input to the round function with a 64-bit subkey generated from the key scheduling
SEED is easily implemented in various software and hardware because it is designed to increase the efficiency of memory storage and the simplicity of generating keys without degrading the security of the algorithm. In particular, it can be effectively adopted in a computing environment that has a restricted resources such as mobile devices, smart cards, and so on
SEED is a national industrial association standard [TTASSEED] and is widely used in South Korea for electronic commerce and financial services operated on wired & wireless PKI
The algorithm specification and object identifiers are described in [SEED-ALG]. The SEED homepage, http://www.kisa.or.kr/seed/seed_eng.html, contains a wealth of information about SEED, including detailed specification, evaluation report, test vectors, and so on
Proposed Cipher Suites
The new cipher suites proposed here have the following definitions:
Key Exchange
The cipher suites defined here differ in the type of certificate and key exchange method. They use the following options:
CipherSuite Key Exchange Algorithm
This document describes a means of negotiating the use of the encrypt-then-MAC security mechanism in place of the existing MAC then-encrypt mechanism in Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS). The MAC-then-encrypt mechanism has been the subject of a number of security vulnerabilities over a period of many years
Negotiating Encrypt-then-MAC
The use of encrypt-then-MAC is negotiated via TLS/DTLS extensions as defined in TLS. On connecting, the client includes the encrypt_then_mac extension in its client_hello if it wishes to use encrypt-then-MAC rather than the default MAC-then-encrypt. If the server is capable of meeting this requirement, it responds with an encrypt_then_mac in its server_hello. The "extension_type" value for this extension SHALL be 22 (0x16), and the "extension_data" field of this extension SHALL be empty. The client and server MUST NOT use encrypt-then-MAC unless both sides have successfully exchanged encrypt_then_mac extensions
Rationale
The use of TLS/DTLS extensions to negotiate an overall switch is preferable to defining new ciphersuites because the latter would result in a Cartesian explosion of suites, potentially requiring duplicating every single existing suite with a new one that uses encrypt-then-MAC. In contrast, the approach presented here requires just a single new extension type with a corresponding minimal-length extension sent by client and server
Another possibility for introducing encrypt-then-MAC would be to make it part of TLS 1.3; however, this would require the implementation and deployment of all of TLS 1.2 just to support a trivial code change in the order of encryption and MAC’ing. In contrast, deploying encrypt-then-MAC via the TLS/DTLS extension mechanism required changing less than a dozen lines of code in one implementation (not including the handling for the new extension type, which was a further 50 or so lines of code)
The use of extensions precludes use with SSL 3.0, but then it’s likely that anything still using that protocol, which is nearly two decades old, will be vulnerable to any number of other attacks anyway, so there seems little point in bending over backwards to accommodate SSL 3.0
Applying Encrypt-then-MAC
Once the use of encrypt-then-MAC has been negotiated, processing of TLS/DTLS packets switches from the standard:
to the new:
with the MAC covering the entire packet up to the start of the MAC value. In TLS notation, the MAC calculation for TLS 1.0 without the explicit Initialization Vector (IV) is:
and for TLS 1.1 and greater with an explicit IV is:
(For DTLS, the sequence number is replaced by the combined epoch and sequence number as per DTLS) The final MAC value is then appended to the encrypted data and padding. This calculation is identical to the existing one, with the exception that the MAC calculation is run over the payload ciphertext (the TLSCipherText PDU) rather than the plaintext (the TLSCompressed PDU)
The overall TLS packet [2] is then:
The equivalent DTLS packet is then:
This is identical to the existing TLS/DTLS layout, with the only difference being that the MAC value is moved outside the encrypted data
Note from the GenericBlockCipher annotation that this only applies to standard block ciphers that have distinct encrypt and MAC operations. It does not apply to GenericStreamCiphers or to GenericAEADCiphers that already include integrity protection with the cipher. If a server receives an encrypt-then-MAC request extension from a client and then selects a stream or Authenticated Encryption with Associated Data (AEAD) ciphersuite, it MUST NOT send an encrypt-then-MAC response extension back to the client
Decryption reverses this processing. The MAC SHALL be evaluated before any further processing such as decryption is performed, and if the MAC verification fails, then processing SHALL terminate immediately. For TLS, a fatal bad_record_mac MUST be generated. For DTLS, the record MUST be discarded, and a fatal bad_record_mac MAY be generated. This immediate response to a bad MAC eliminates any timing channels that may be available through the use of manipulated packet data
Some implementations may prefer to use a truncated MAC rather than a full-length one. In this case, they MAY negotiate the use of a truncated MAC through the TLS truncated_hmac extension as defined in TLS-Ext
Rehandshake Issues
The status of encrypt-then-MAC vs. MAC-then-encrypt can potentially change during one or more rehandshakes. Implementations SHOULD retain the current session state across all rehandshakes for that session. (In other words, if the mechanism for the current session is X, then the renegotiated session should also use X.) Although implementations SHOULD NOT change the state during a rehandshake, if they wish to be more flexible, then the following rules apply:
Current Session | Renegotiated Session | Action to Take |
---|---|---|
MAC-then-encrypt | MAC-then-encrypt | No change |
MAC-then-encrypt | Encrypt-then-MAC | Upgrade to Encrypt-then-MAC |
Encrypt-then-MAC | MAC-then-encrypt | Error |
Encrypt-then-MAC | Encrypt-then-MAC | No change |
As the above table points out, implementations MUST NOT renegotiate a downgrade from encrypt-then-MAC to MAC-then-encrypt. Note that a client or server that doesn’t wish to implement the mechanism-change during-rehandshake ability can (as a client) not request a mechanism change and (as a server) deny the mechanism change
Note that these rules apply across potentially many rehandshakes. For example, if a session were in the encrypt-then-MAC state and a rehandshake selected a GenericAEADCiphers ciphersuite and a subsequent rehandshake then selected a MAC-then-encrypt ciphersuite, this would be an error since the renegotiation process has resulted in a downgrade from encrypt-then-MAC to MAC-then-encrypt (via the AEAD ciphersuite)
(As the text above has already pointed out, implementations SHOULD avoid having to deal with these ciphersuite calisthenics by retaining the initially negotiated mechanism across all rehandshakes)
If an upgrade from MAC-then-encrypt to encrypt-then-MAC is negotiated as per the second line in the table above, then the change will take place in the first message that follows the Change Cipher Spec (CCS) message. In other words, all messages up to and including the CCS will use MAC-then-encrypt, and then the message that follows will continue with encrypt-then-MAC
Security Considerations
This document defines encrypt-then-MAC, an improved security mechanism to replace the current MAC-then-encrypt one. Encrypt-then MAC is regarded as more secure than the current mechanism and should mitigate or eliminate a number of attacks on the current mechanism, provided that the instructions on MAC processing given in Section 3 are applied
An active attacker who can emulate a client or server with extension intolerance may cause some implementations to fall back to older protocol versions that don’t support extensions, which will in turn force a fallback to non-encrypt-then-MAC behaviour. A straightforward solution to this problem is to avoid fallback to older, less secure protocol versions. If fallback behaviour is unavoidable, then mechanisms to address this issue, which affects all capabilities that are negotiated via TLS extensions, are being developed by the TLS working group. Anyone concerned about this type of attack should consult the TLS working group documents for guidance on appropriate defence mechanisms
IANA Considerations
IANA has added the extension code point 22 (0x16) for the encrypt_then_mac extension to the TLS "ExtensionType Values" registry as specified in TLS
[1] http://orm-chimera-prod.s3.amazonaws.com/1230000000545/ch04.html
[2] https://tools.ietf.org/html/rfc7366
For API Documentation:
For Additional Documentation:
The source code contained or described herein and all documents related to the source code (herein called "Material") are owned by John Peter Greninger and Sheila Rocha Greninger. Title to the Material remains with John Peter Greninger and Sheila Rocha Greninger. The Material contains trade secrets and proprietary and confidential information of John Peter Greninger and Sheila Rocha Greninger. The Material is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without prior express written consent of John Peter Greninger and Sheila Rocha Greninger (both are required)
No license under any patent, copyright, trade secret, or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel, or otherwise. Any license under such intellectual property rights must be express and approved by John Peter Greninger and Sheila Rocha Greninger in writing
Licensing information can be found at www.protocolpp.com/license with use of the binary forms permitted provided that the following conditions are met:
Use of the source code requires purchase of the source code. Source code can be purchased at www.protocolpp.com/shop
The name of its contributor may not be used to endorse or promote products derived from this software without specific prior written permission and licensing
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTOR "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE