Update structure for partials and examples
This commit is contained in:
parent
b1b3d6a960
commit
531ddf0721
89 changed files with 79 additions and 79 deletions
17
modules/ROOT/examples/C-Arithmetic-add.adoc
Normal file
17
modules/ROOT/examples/C-Arithmetic-add.adoc
Normal file
|
@ -0,0 +1,17 @@
|
|||
|
||||
void report_overflow(void);
|
||||
|
||||
int
|
||||
add(int a, int b)
|
||||
{
|
||||
int result = a + b;
|
||||
if (a < 0 || b < 0) {
|
||||
return -1;
|
||||
}
|
||||
// The compiler can optimize away the following if statement.
|
||||
if (result < 0) {
|
||||
report_overflow();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
13
modules/ROOT/examples/C-Arithmetic-add_unsigned.adoc
Normal file
13
modules/ROOT/examples/C-Arithmetic-add_unsigned.adoc
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
void report_overflow(void);
|
||||
|
||||
unsigned
|
||||
add_unsigned(unsigned a, unsigned b)
|
||||
{
|
||||
unsigned sum = a + b;
|
||||
if (sum < a) { // or sum < b
|
||||
report_overflow();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
10
modules/ROOT/examples/C-Arithmetic-mult.adoc
Normal file
10
modules/ROOT/examples/C-Arithmetic-mult.adoc
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
unsigned
|
||||
mul(unsigned a, unsigned b)
|
||||
{
|
||||
if (b && a > ((unsigned)-1) / b) {
|
||||
report_overflow();
|
||||
}
|
||||
return a * b;
|
||||
}
|
||||
|
8
modules/ROOT/examples/C-Globals-String_Array.adoc
Normal file
8
modules/ROOT/examples/C-Globals-String_Array.adoc
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
static const char *const string_list[] = {
|
||||
"first",
|
||||
"second",
|
||||
"third",
|
||||
NULL
|
||||
};
|
||||
|
45
modules/ROOT/examples/C-Pointers-remaining.adoc
Normal file
45
modules/ROOT/examples/C-Pointers-remaining.adoc
Normal file
|
@ -0,0 +1,45 @@
|
|||
|
||||
ssize_t
|
||||
extract_strings(const char *in, size_t inlen, char **out, size_t outlen)
|
||||
{
|
||||
const char *inp = in;
|
||||
const char *inend = in + inlen;
|
||||
char **outp = out;
|
||||
char **outend = out + outlen;
|
||||
|
||||
while (inp != inend) {
|
||||
size_t len;
|
||||
char *s;
|
||||
if (outp == outend) {
|
||||
errno = ENOSPC;
|
||||
goto err;
|
||||
}
|
||||
len = (unsigned char)*inp;
|
||||
++inp;
|
||||
if (len > (size_t)(inend - inp)) {
|
||||
errno = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
s = malloc(len + 1);
|
||||
if (s == NULL) {
|
||||
goto err;
|
||||
}
|
||||
memcpy(s, inp, len);
|
||||
inp += len;
|
||||
s[len] = '\0';
|
||||
*outp = s;
|
||||
++outp;
|
||||
}
|
||||
return outp - out;
|
||||
err:
|
||||
{
|
||||
int errno_old = errno;
|
||||
while (out != outp) {
|
||||
free(*out);
|
||||
++out;
|
||||
}
|
||||
errno = errno_old;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
14
modules/ROOT/examples/C-String-Functions-format.adoc
Normal file
14
modules/ROOT/examples/C-String-Functions-format.adoc
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
void log_format(const char *format, ...) __attribute__((format(printf, 1, 2)));
|
||||
|
||||
void
|
||||
log_format(const char *format, ...)
|
||||
{
|
||||
char buf[1000];
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vsnprintf(buf, sizeof(buf), format, ap);
|
||||
va_end(ap);
|
||||
log_string(buf);
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
char buf[512];
|
||||
char *current = buf;
|
||||
const char *const end = buf + sizeof(buf);
|
||||
for (struct item *it = data; it->key; ++it) {
|
||||
snprintf(current, end - current, "%s%s=%d",
|
||||
current == buf ? "" : ", ", it->key, it->value);
|
||||
current += strlen(current);
|
||||
}
|
||||
|
4
modules/ROOT/examples/C-String-Functions-snprintf.adoc
Normal file
4
modules/ROOT/examples/C-String-Functions-snprintf.adoc
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
char fraction[30];
|
||||
snprintf(fraction, sizeof(fraction), "%d/%d", numerator, denominator);
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
buf[0] = '\0';
|
||||
strncat(buf, data, sizeof(buf) - 1);
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
char buf[10];
|
||||
snprintf(buf, sizeof(buf), "%s", prefix);
|
||||
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s", data);
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
snprintf(buf, sizeof(buf), "%s%s", prefix, data);
|
||||
|
5
modules/ROOT/examples/C-String-Functions-strncpy.adoc
Normal file
5
modules/ROOT/examples/C-String-Functions-strncpy.adoc
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
char buf[10];
|
||||
strncpy(buf, data, sizeof(buf));
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
|
18
modules/ROOT/examples/Features-HSM-GNUTLS-PIN.adoc
Normal file
18
modules/ROOT/examples/Features-HSM-GNUTLS-PIN.adoc
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
int pin_function(void *userdata, int attempt, const char *token_url,
|
||||
const char *token_label, unsigned flags, char *pin, size_t pin_max)
|
||||
{
|
||||
if (flags & GNUTLS_PIN_FINAL_TRY)
|
||||
printf("This is the final try before locking!\n");
|
||||
if (flags & GNUTLS_PIN_COUNT_LOW)
|
||||
printf("Only few tries left before locking!\n");
|
||||
if (flags & GNUTLS_PIN_WRONG)
|
||||
printf("Wrong PIN has been provided in the previous attempt\n");
|
||||
|
||||
/* userdata is the second value passed to gnutls_pkcs11_set_pin_function()
|
||||
* in this example we passed the PIN as a null terminated value.
|
||||
*/
|
||||
snprintf(pin, pin_max, "%s", (char*)userdata);
|
||||
return 0;
|
||||
}
|
||||
|
40
modules/ROOT/examples/Features-HSM-GNUTLS.adoc
Normal file
40
modules/ROOT/examples/Features-HSM-GNUTLS.adoc
Normal file
|
@ -0,0 +1,40 @@
|
|||
|
||||
if (module_path) {
|
||||
ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = gnutls_pkcs11_add_provider(module_path, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (key_pass)
|
||||
gnutls_pkcs11_set_pin_function(pin_function, key_pass);
|
||||
|
||||
ret = gnutls_privkey_init(&private_key);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = gnutls_privkey_import_url(private_key, private_key_name, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = gnutls_privkey_sign_data(private_key, GNUTLS_DIG_SHA256, 0,
|
||||
&testdata, &signature);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
gnutls_privkey_deinit(private_key);
|
||||
gnutls_free(signature.data);
|
||||
|
23
modules/ROOT/examples/Features-HSM-NSS-PIN.adoc
Normal file
23
modules/ROOT/examples/Features-HSM-NSS-PIN.adoc
Normal file
|
@ -0,0 +1,23 @@
|
|||
|
||||
char *passwdcb(PK11SlotInfo * slot, PRBool retry, void *arg)
|
||||
{
|
||||
if (!isatty(STDIN_FILENO) && retry) {
|
||||
/* we're just reading from a file, and the value is known to be wrong,
|
||||
* don't keep bounding the token with the wrong password. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (retry) {
|
||||
printf("Warning: Wrong PIN has been provided in the previous attempt\n");
|
||||
if (PK11_IsHW(slot)) {
|
||||
printf
|
||||
(" NOTE: multiple pin failures could result in locking your device\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (pin == NULL)
|
||||
return pin;
|
||||
else
|
||||
return strdup(pin);
|
||||
}
|
||||
|
56
modules/ROOT/examples/Features-HSM-NSS.adoc
Normal file
56
modules/ROOT/examples/Features-HSM-NSS.adoc
Normal file
|
@ -0,0 +1,56 @@
|
|||
|
||||
SECStatus rv;
|
||||
CERTCertificate *cert = NULL;
|
||||
SECKEYPrivateKey *pvtkey = NULL;
|
||||
SECItem signature = { siBuffer, NULL, 0 };
|
||||
SECOidTag algTag;
|
||||
int r = 1;
|
||||
unsigned char buf[] = "test data to sign";
|
||||
const char *cert_name;
|
||||
unsigned i;
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "usage: %s [cert name] [PIN]\n\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cert_name = argv[1];
|
||||
pin = argv[2];
|
||||
|
||||
PK11_SetPasswordFunc(passwdcb);
|
||||
NSS_InitializePRErrorTable();
|
||||
rv = NSS_Init(".");
|
||||
if (rv != SECSuccess) {
|
||||
fprintf(stderr, "NSS initialization failed (err %d)\n", PR_GetError());
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cert = PK11_FindCertFromNickname(cert_name, NULL);
|
||||
if (cert == NULL) {
|
||||
fprintf(stderr, "Couldn't find cert %s in NSS db (err %d: %s)\n",
|
||||
cert_name, PR_GetError(), PORT_ErrorToString(PR_GetError()));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Buffer being signed = \n%s\n", buf);
|
||||
|
||||
pvtkey = PK11_FindKeyByAnyCert(cert, NULL);
|
||||
if (pvtkey == NULL) {
|
||||
fprintf(stderr, "Couldn't find private key for cert %s (err %d: %s)\n",
|
||||
cert_name, PR_GetError(), PORT_ErrorToString(PR_GetError()));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* get the algtag. Pick the default hash algorithm */
|
||||
algTag = SEC_GetSignatureAlgorithmOidTag(pvtkey->keyType, SEC_OID_UNKNOWN);
|
||||
|
||||
fprintf(stderr, "Signing with alg = %s (%d)\n",
|
||||
SECOID_FindOIDTagDescription(algTag), algTag);
|
||||
|
||||
rv = SEC_SignData(&signature, buf, sizeof(buf)-1, pvtkey, algTag);
|
||||
if (rv != SECSuccess) {
|
||||
fprintf(stderr, "sign with Private Key failed (err %d: %s)\n",
|
||||
PR_GetError(), PORT_ErrorToString(PR_GetError()));
|
||||
goto cleanup;
|
||||
}
|
||||
|
64
modules/ROOT/examples/Features-HSM-OpenSSL.adoc
Normal file
64
modules/ROOT/examples/Features-HSM-OpenSSL.adoc
Normal file
|
@ -0,0 +1,64 @@
|
|||
|
||||
OpenSSL_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
ERR_clear_error();
|
||||
ENGINE_load_builtin_engines();
|
||||
|
||||
e = ENGINE_by_id("pkcs11");
|
||||
if (!e) {
|
||||
display_openssl_errors(__LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (module_path) {
|
||||
fprintf(stderr, "loading: %s\n", module_path);
|
||||
if (!ENGINE_ctrl_cmd_string(e, "MODULE_PATH", module_path, 0)) {
|
||||
display_openssl_errors(__LINE__);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ENGINE_init(e)) {
|
||||
display_openssl_errors(__LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (key_pass && !ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) {
|
||||
display_openssl_errors(__LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
private_key = ENGINE_load_private_key(e, private_key_name, NULL, NULL);
|
||||
if (!private_key) {
|
||||
fprintf(stderr, "cannot load: %s\n", private_key_name);
|
||||
display_openssl_errors(__LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
display_openssl_errors(__LINE__);
|
||||
|
||||
digest_algo = EVP_get_digestbyname("sha256");
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
if (EVP_DigestInit(&ctx, digest_algo) <= 0) {
|
||||
display_openssl_errors(__LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
EVP_SignInit(&ctx, digest_algo);
|
||||
|
||||
#define TEST_DATA "test data"
|
||||
if (EVP_SignUpdate(&ctx, TEST_DATA, sizeof(TEST_DATA) - 1) <= 0) {
|
||||
display_openssl_errors(__LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
n = sizeof(buf);
|
||||
if (EVP_SignFinal(&ctx, buf, &n, private_key) <= 0) {
|
||||
display_openssl_errors(__LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
EVP_PKEY_free(private_key);
|
||||
ENGINE_finish(e);
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
// Create the session object.
|
||||
gnutls_session_t session;
|
||||
ret = gnutls_init(&session, GNUTLS_CLIENT);
|
||||
if (ret != GNUTLS_E_SUCCESS) {
|
||||
fprintf(stderr, "error: gnutls_init: %s\n",
|
||||
gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Configure the cipher preferences.
|
||||
const char *errptr = NULL;
|
||||
ret = gnutls_priority_set_direct(session, "NORMAL", &errptr);
|
||||
if (ret != GNUTLS_E_SUCCESS) {
|
||||
fprintf(stderr, "error: gnutls_priority_set_direct: %s\n"
|
||||
"error: at: \"%s\"\n", gnutls_strerror(ret), errptr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Install the trusted certificates.
|
||||
ret = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred);
|
||||
if (ret != GNUTLS_E_SUCCESS) {
|
||||
fprintf(stderr, "error: gnutls_credentials_set: %s\n",
|
||||
gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Associate the socket with the session object and set the server
|
||||
// name.
|
||||
gnutls_transport_set_int(session, sockfd);
|
||||
ret = gnutls_server_name_set(session, GNUTLS_NAME_DNS,
|
||||
host, strlen(host));
|
||||
if (ret != GNUTLS_E_SUCCESS) {
|
||||
fprintf(stderr, "error: gnutls_server_name_set: %s\n",
|
||||
gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Establish the session.
|
||||
ret = gnutls_handshake(session);
|
||||
if (ret != GNUTLS_E_SUCCESS) {
|
||||
fprintf(stderr, "error: gnutls_handshake: %s\n",
|
||||
gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
// Load the trusted CA certificates.
|
||||
gnutls_certificate_credentials_t cred = NULL;
|
||||
int ret = gnutls_certificate_allocate_credentials (&cred);
|
||||
if (ret != GNUTLS_E_SUCCESS) {
|
||||
fprintf(stderr, "error: gnutls_certificate_allocate_credentials: %s\n",
|
||||
gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = gnutls_certificate_set_x509_system_trust(cred);
|
||||
if (ret == 0) {
|
||||
fprintf(stderr, "error: no certificates found in system trust store\n");
|
||||
exit(1);
|
||||
}
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error: gnutls_certificate_set_x509_system_trust: %s\n",
|
||||
gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
38
modules/ROOT/examples/Features-TLS-Client-GNUTLS-Verify.adoc
Normal file
38
modules/ROOT/examples/Features-TLS-Client-GNUTLS-Verify.adoc
Normal file
|
@ -0,0 +1,38 @@
|
|||
|
||||
// Obtain the server certificate chain. The server certificate
|
||||
// itself is stored in the first element of the array.
|
||||
unsigned certslen = 0;
|
||||
const gnutls_datum_t *const certs =
|
||||
gnutls_certificate_get_peers(session, &certslen);
|
||||
if (certs == NULL || certslen == 0) {
|
||||
fprintf(stderr, "error: could not obtain peer certificate\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Validate the certificate chain.
|
||||
unsigned status = (unsigned)-1;
|
||||
ret = gnutls_certificate_verify_peers3(session, host, &status);
|
||||
if (ret != GNUTLS_E_SUCCESS) {
|
||||
fprintf(stderr, "error: gnutls_certificate_verify_peers3: %s\n",
|
||||
gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
if (status != 0 && !certificate_validity_override(certs[0])) {
|
||||
gnutls_datum_t msg;
|
||||
#if GNUTLS_VERSION_AT_LEAST_3_1_4
|
||||
int type = gnutls_certificate_type_get (session);
|
||||
ret = gnutls_certificate_verification_status_print(status, type, &out, 0);
|
||||
#else
|
||||
ret = -1;
|
||||
#endif
|
||||
if (ret == 0) {
|
||||
fprintf(stderr, "error: %s\n", msg.data);
|
||||
gnutls_free(msg.data);
|
||||
exit(1);
|
||||
} else {
|
||||
fprintf(stderr, "error: certificate validation failed with code 0x%x\n",
|
||||
status);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
11
modules/ROOT/examples/Features-TLS-Client-NSS-Close.adoc
Normal file
11
modules/ROOT/examples/Features-TLS-Client-NSS-Close.adoc
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
// Send close_notify alert.
|
||||
if (PR_Shutdown(nspr, PR_SHUTDOWN_BOTH) != PR_SUCCESS) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: PR_Read error %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
// Closes the underlying POSIX file descriptor, too.
|
||||
PR_Close(nspr);
|
||||
|
76
modules/ROOT/examples/Features-TLS-Client-NSS-Connect.adoc
Normal file
76
modules/ROOT/examples/Features-TLS-Client-NSS-Connect.adoc
Normal file
|
@ -0,0 +1,76 @@
|
|||
|
||||
// Wrap the POSIX file descriptor. This is an internal NSPR
|
||||
// function, but it is very unlikely to change.
|
||||
PRFileDesc* nspr = PR_ImportTCPSocket(sockfd);
|
||||
sockfd = -1; // Has been taken over by NSPR.
|
||||
|
||||
// Add the SSL layer.
|
||||
{
|
||||
PRFileDesc *model = PR_NewTCPSocket();
|
||||
PRFileDesc *newfd = SSL_ImportFD(NULL, model);
|
||||
if (newfd == NULL) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: NSPR error code %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
model = newfd;
|
||||
newfd = NULL;
|
||||
if (SSL_OptionSet(model, SSL_ENABLE_SSL2, PR_FALSE) != SECSuccess) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: set SSL_ENABLE_SSL2 error %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
if (SSL_OptionSet(model, SSL_V2_COMPATIBLE_HELLO, PR_FALSE) != SECSuccess) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: set SSL_V2_COMPATIBLE_HELLO error %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
if (SSL_OptionSet(model, SSL_ENABLE_DEFLATE, PR_FALSE) != SECSuccess) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: set SSL_ENABLE_DEFLATE error %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Allow overriding invalid certificate.
|
||||
if (SSL_BadCertHook(model, bad_certificate, (char *)host) != SECSuccess) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: SSL_BadCertHook error %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
newfd = SSL_ImportFD(model, nspr);
|
||||
if (newfd == NULL) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: SSL_ImportFD error %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
nspr = newfd;
|
||||
PR_Close(model);
|
||||
}
|
||||
|
||||
// Perform the handshake.
|
||||
if (SSL_ResetHandshake(nspr, PR_FALSE) != SECSuccess) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: SSL_ResetHandshake error %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
if (SSL_SetURL(nspr, host) != SECSuccess) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: SSL_SetURL error %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
if (SSL_ForceHandshake(nspr) != SECSuccess) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: SSL_ForceHandshake error %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
// Create the socket and connect it at the TCP layer.
|
||||
SSLSocket socket = (SSLSocket) ctx.getSocketFactory()
|
||||
.createSocket(host, port);
|
||||
|
||||
// Disable the Nagle algorithm.
|
||||
socket.setTcpNoDelay(true);
|
||||
|
||||
// Adjust ciphers and protocols.
|
||||
socket.setSSLParameters(params);
|
||||
|
||||
// Perform the handshake.
|
||||
socket.startHandshake();
|
||||
|
||||
// Validate the host name. The match() method throws
|
||||
// CertificateException on failure.
|
||||
X509Certificate peer = (X509Certificate)
|
||||
socket.getSession().getPeerCertificates()[0];
|
||||
// This is the only way to perform host name checking on OpenJDK 6.
|
||||
HostnameChecker.getInstance(HostnameChecker.TYPE_TLS).match(
|
||||
host, peer);
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
// Create the context. Specify the SunJSSE provider to avoid
|
||||
// picking up third-party providers. Try the TLS 1.2 provider
|
||||
// first, then fall back to TLS 1.0.
|
||||
SSLContext ctx;
|
||||
try {
|
||||
ctx = SSLContext.getInstance("TLSv1.2", "SunJSSE");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
try {
|
||||
ctx = SSLContext.getInstance("TLSv1", "SunJSSE");
|
||||
} catch (NoSuchAlgorithmException e1) {
|
||||
// The TLS 1.0 provider should always be available.
|
||||
throw new AssertionError(e1);
|
||||
} catch (NoSuchProviderException e1) {
|
||||
throw new AssertionError(e1);
|
||||
}
|
||||
} catch (NoSuchProviderException e) {
|
||||
// The SunJSSE provider should always be available.
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
ctx.init(null, null, null);
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
SSLContext ctx;
|
||||
try {
|
||||
ctx = SSLContext.getInstance("TLSv1.2", "SunJSSE");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
try {
|
||||
ctx = SSLContext.getInstance("TLSv1", "SunJSSE");
|
||||
} catch (NoSuchAlgorithmException e1) {
|
||||
throw new AssertionError(e1);
|
||||
} catch (NoSuchProviderException e1) {
|
||||
throw new AssertionError(e1);
|
||||
}
|
||||
} catch (NoSuchProviderException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
MyTrustManager tm = new MyTrustManager(certHash);
|
||||
ctx.init(null, new TrustManager[] {tm}, null);
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
params.setEndpointIdentificationAlgorithm("HTTPS");
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import sun.security.util.HostnameChecker;
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
public class MyTrustManager implements X509TrustManager {
|
||||
private final byte[] certHash;
|
||||
|
||||
public MyTrustManager(byte[] certHash) throws Exception {
|
||||
this.certHash = certHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType)
|
||||
throws CertificateException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain,
|
||||
String authType) throws CertificateException {
|
||||
byte[] digest = getCertificateDigest(chain[0]);
|
||||
String digestHex = formatHex(digest);
|
||||
|
||||
if (Arrays.equals(digest, certHash)) {
|
||||
System.err.println("info: accepting certificate: " + digestHex);
|
||||
} else {
|
||||
throw new CertificateException("certificate rejected: " +
|
||||
digestHex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
socket.getOutputStream().write("GET / HTTP/1.0\r\n\r\n"
|
||||
.getBytes(Charset.forName("UTF-8")));
|
||||
byte[] buffer = new byte[4096];
|
||||
int count = socket.getInputStream().read(buffer);
|
||||
System.out.write(buffer, 0, count);
|
||||
|
67
modules/ROOT/examples/Features-TLS-Client-OpenSSL-CTX.adoc
Normal file
67
modules/ROOT/examples/Features-TLS-Client-OpenSSL-CTX.adoc
Normal file
|
@ -0,0 +1,67 @@
|
|||
|
||||
// Configure a client connection context. Send a hendshake for the
|
||||
// highest supported TLS version, and disable compression.
|
||||
const SSL_METHOD *const req_method = SSLv23_client_method();
|
||||
SSL_CTX *const ctx = SSL_CTX_new(req_method);
|
||||
if (ctx == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
exit(1);
|
||||
}
|
||||
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION);
|
||||
|
||||
// Adjust the ciphers list based on a whitelist. First enable all
|
||||
// ciphers of at least medium strength, to get the list which is
|
||||
// compiled into OpenSSL.
|
||||
if (SSL_CTX_set_cipher_list(ctx, "HIGH:MEDIUM") != 1) {
|
||||
ERR_print_errors(bio_err);
|
||||
exit(1);
|
||||
}
|
||||
{
|
||||
// Create a dummy SSL session to obtain the cipher list.
|
||||
SSL *ssl = SSL_new(ctx);
|
||||
if (ssl == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
exit(1);
|
||||
}
|
||||
STACK_OF(SSL_CIPHER) *active_ciphers = SSL_get_ciphers(ssl);
|
||||
if (active_ciphers == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
exit(1);
|
||||
}
|
||||
// Whitelist of candidate ciphers.
|
||||
static const char *const candidates[] = {
|
||||
"AES128-GCM-SHA256", "AES128-SHA256", "AES256-SHA256", // strong ciphers
|
||||
"AES128-SHA", "AES256-SHA", // strong ciphers, also in older versions
|
||||
"RC4-SHA", "RC4-MD5", // backwards compatibility, supposed to be weak
|
||||
"DES-CBC3-SHA", "DES-CBC3-MD5", // more backwards compatibility
|
||||
NULL
|
||||
};
|
||||
// Actually selected ciphers.
|
||||
char ciphers[300];
|
||||
ciphers[0] = '\0';
|
||||
for (const char *const *c = candidates; *c; ++c) {
|
||||
for (int i = 0; i < sk_SSL_CIPHER_num(active_ciphers); ++i) {
|
||||
if (strcmp(SSL_CIPHER_get_name(sk_SSL_CIPHER_value(active_ciphers, i)),
|
||||
*c) == 0) {
|
||||
if (*ciphers) {
|
||||
strcat(ciphers, ":");
|
||||
}
|
||||
strcat(ciphers, *c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SSL_free(ssl);
|
||||
// Apply final cipher list.
|
||||
if (SSL_CTX_set_cipher_list(ctx, ciphers) != 1) {
|
||||
ERR_print_errors(bio_err);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Load the set of trusted root certificates.
|
||||
if (!SSL_CTX_set_default_verify_paths(ctx)) {
|
||||
ERR_print_errors(bio_err);
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
// Create the connection object.
|
||||
SSL *ssl = SSL_new(ctx);
|
||||
if (ssl == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
exit(1);
|
||||
}
|
||||
SSL_set_fd(ssl, sockfd);
|
||||
|
||||
// Enable the ServerNameIndication extension
|
||||
if (!SSL_set_tlsext_host_name(ssl, host)) {
|
||||
ERR_print_errors(bio_err);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Perform the TLS handshake with the server.
|
||||
ret = SSL_connect(ssl);
|
||||
if (ret != 1) {
|
||||
// Error status can be 0 or negative.
|
||||
ssl_print_error_and_exit(ssl, "SSL_connect", ret);
|
||||
}
|
||||
|
||||
// Obtain the server certificate.
|
||||
X509 *peercert = SSL_get_peer_certificate(ssl);
|
||||
if (peercert == NULL) {
|
||||
fprintf(stderr, "peer certificate missing");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Check the certificate verification result. Allow an explicit
|
||||
// certificate validation override in case verification fails.
|
||||
int verifystatus = SSL_get_verify_result(ssl);
|
||||
if (verifystatus != X509_V_OK && !certificate_validity_override(peercert)) {
|
||||
fprintf(stderr, "SSL_connect: verify result: %s\n",
|
||||
X509_verify_cert_error_string(verifystatus));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Check if the server certificate matches the host name used to
|
||||
// establish the connection.
|
||||
// FIXME: Currently needs OpenSSL 1.1.
|
||||
if (X509_check_host(peercert, (const unsigned char *)host, strlen(host),
|
||||
0) != 1
|
||||
&& !certificate_host_name_override(peercert, host)) {
|
||||
fprintf(stderr, "SSL certificate does not match host name\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
X509_free(peercert);
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
const char *const req = "GET / HTTP/1.0\r\n\r\n";
|
||||
if (SSL_write(ssl, req, strlen(req)) < 0) {
|
||||
ssl_print_error_and_exit(ssl, "SSL_write", ret);
|
||||
}
|
||||
char buf[4096];
|
||||
ret = SSL_read(ssl, buf, sizeof(buf));
|
||||
if (ret < 0) {
|
||||
ssl_print_error_and_exit(ssl, "SSL_read", ret);
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
// The following call prints an error message and calls exit() if
|
||||
// the OpenSSL configuration file is unreadable.
|
||||
OPENSSL_config(NULL);
|
||||
// Provide human-readable error messages.
|
||||
SSL_load_error_strings();
|
||||
// Register ciphers.
|
||||
SSL_library_init();
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
sock = ssl.wrap_socket(sock,
|
||||
ciphers="HIGH:-aNULL:-eNULL:-PSK:RC4-SHA:RC4-MD5",
|
||||
ssl_version=ssl.PROTOCOL_TLSv1,
|
||||
cert_reqs=ssl.CERT_REQUIRED,
|
||||
ca_certs='/etc/ssl/certs/ca-bundle.crt')
|
||||
# getpeercert() triggers the handshake as a side effect.
|
||||
if not check_host_name(sock.getpeercert(), host):
|
||||
raise IOError("peer certificate does not match host name")
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
def check_host_name(peercert, name):
|
||||
"""Simple certificate/host name checker. Returns True if the
|
||||
certificate matches, False otherwise. Does not support
|
||||
wildcards."""
|
||||
# Check that the peer has supplied a certificate.
|
||||
# None/{} is not acceptable.
|
||||
if not peercert:
|
||||
return False
|
||||
if peercert.has_key("subjectAltName"):
|
||||
for typ, val in peercert["subjectAltName"]:
|
||||
if typ == "DNS" and val == name:
|
||||
return True
|
||||
else:
|
||||
# Only check the subject DN if there is no subject alternative
|
||||
# name.
|
||||
cn = None
|
||||
for attr, val in peercert["subject"]:
|
||||
# Use most-specific (last) commonName attribute.
|
||||
if attr == "commonName":
|
||||
cn = val
|
||||
if cn is not None:
|
||||
return cn == name
|
||||
return False
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
gnutls_certificate_free_credentials(cred);
|
||||
|
10
modules/ROOT/examples/Features-TLS-GNUTLS-Disconnect.adoc
Normal file
10
modules/ROOT/examples/Features-TLS-GNUTLS-Disconnect.adoc
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
// Initiate an orderly connection shutdown.
|
||||
ret = gnutls_bye(session, GNUTLS_SHUT_RDWR);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error: gnutls_bye: %s\n", gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
// Free the session object.
|
||||
gnutls_deinit(session);
|
||||
|
5
modules/ROOT/examples/Features-TLS-GNUTLS-Init.adoc
Normal file
5
modules/ROOT/examples/Features-TLS-GNUTLS-Init.adoc
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
// This is only necessary if compatibility with GnuTLS prior to
|
||||
// 3.3.0 is required.
|
||||
gnutls_global_init();
|
||||
|
14
modules/ROOT/examples/Features-TLS-GNUTLS-Use.adoc
Normal file
14
modules/ROOT/examples/Features-TLS-GNUTLS-Use.adoc
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
char buf[4096];
|
||||
snprintf(buf, sizeof(buf), "GET / HTTP/1.0\r\nHost: %s\r\n\r\n", host);
|
||||
ret = gnutls_record_send(session, buf, strlen(buf));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error: gnutls_record_send: %s\n", gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
ret = gnutls_record_recv(session, buf, sizeof(buf));
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "error: gnutls_record_recv: %s\n", gnutls_strerror(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
4
modules/ROOT/examples/Features-TLS-NSS-Close.adoc
Normal file
4
modules/ROOT/examples/Features-TLS-NSS-Close.adoc
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
SECMOD_DestroyModule(module);
|
||||
NSS_ShutdownContext(ctx);
|
||||
|
16
modules/ROOT/examples/Features-TLS-NSS-Includes.adoc
Normal file
16
modules/ROOT/examples/Features-TLS-NSS-Includes.adoc
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
// NSPR include files
|
||||
#include <prerror.h>
|
||||
#include <prinit.h>
|
||||
|
||||
// NSS include files
|
||||
#include <nss.h>
|
||||
#include <pk11pub.h>
|
||||
#include <secmod.h>
|
||||
#include <ssl.h>
|
||||
#include <sslproto.h>
|
||||
|
||||
// Private API, no other way to turn a POSIX file descriptor into an
|
||||
// NSPR handle.
|
||||
NSPR_API(PRFileDesc*) PR_ImportTCPSocket(int);
|
||||
|
67
modules/ROOT/examples/Features-TLS-NSS-Init.adoc
Normal file
67
modules/ROOT/examples/Features-TLS-NSS-Init.adoc
Normal file
|
@ -0,0 +1,67 @@
|
|||
|
||||
PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
|
||||
NSSInitContext *const ctx =
|
||||
NSS_InitContext("sql:/etc/pki/nssdb", "", "", "", NULL,
|
||||
NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
|
||||
if (ctx == NULL) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: NSPR error code %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Ciphers to enable.
|
||||
static const PRUint16 good_ciphers[] = {
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_RSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_RSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA,
|
||||
TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
SSL_RSA_WITH_3DES_EDE_CBC_SHA,
|
||||
SSL_NULL_WITH_NULL_NULL // sentinel
|
||||
};
|
||||
|
||||
// Check if the current policy allows any strong ciphers. If it
|
||||
// doesn't, set the cipher suite policy. This is not thread-safe
|
||||
// and has global impact. Consequently, we only do it if absolutely
|
||||
// necessary.
|
||||
int found_good_cipher = 0;
|
||||
for (const PRUint16 *p = good_ciphers; *p != SSL_NULL_WITH_NULL_NULL;
|
||||
++p) {
|
||||
PRInt32 policy;
|
||||
if (SSL_CipherPolicyGet(*p, &policy) != SECSuccess) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: policy for cipher %u: error %d: %s\n",
|
||||
(unsigned)*p, err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
if (policy == SSL_ALLOWED) {
|
||||
fprintf(stderr, "info: found cipher %x\n", (unsigned)*p);
|
||||
found_good_cipher = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found_good_cipher) {
|
||||
if (NSS_SetDomesticPolicy() != SECSuccess) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: NSS_SetDomesticPolicy: error %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the trusted certificate store.
|
||||
char module_name[] = "library=libnssckbi.so name=\"Root Certs\"";
|
||||
SECMODModule *module = SECMOD_LoadUserModule(module_name, NULL, PR_FALSE);
|
||||
if (module == NULL || !module->loaded) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: NSPR error code %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
|
18
modules/ROOT/examples/Features-TLS-NSS-Use.adoc
Normal file
18
modules/ROOT/examples/Features-TLS-NSS-Use.adoc
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
char buf[4096];
|
||||
snprintf(buf, sizeof(buf), "GET / HTTP/1.0\r\nHost: %s\r\n\r\n", host);
|
||||
PRInt32 ret = PR_Write(nspr, buf, strlen(buf));
|
||||
if (ret < 0) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: PR_Write error %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
ret = PR_Read(nspr, buf, sizeof(buf));
|
||||
if (ret < 0) {
|
||||
const PRErrorCode err = PR_GetError();
|
||||
fprintf(stderr, "error: PR_Read error %d: %s\n",
|
||||
err, PR_ErrorToName(err));
|
||||
exit(1);
|
||||
}
|
||||
|
8
modules/ROOT/examples/Features-TLS-Nagle.adoc
Normal file
8
modules/ROOT/examples/Features-TLS-Nagle.adoc
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
const int val = 1;
|
||||
int ret = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
|
||||
if (ret < 0) {
|
||||
perror("setsockopt(TCP_NODELAY)");
|
||||
exit(1);
|
||||
}
|
||||
|
23
modules/ROOT/examples/Features-TLS-OpenJDK-Parameters.adoc
Normal file
23
modules/ROOT/examples/Features-TLS-OpenJDK-Parameters.adoc
Normal file
|
@ -0,0 +1,23 @@
|
|||
|
||||
// Prepare TLS parameters. These have to applied to every TLS
|
||||
// socket before the handshake is triggered.
|
||||
SSLParameters params = ctx.getDefaultSSLParameters();
|
||||
// Do not send an SSL-2.0-compatible Client Hello.
|
||||
ArrayList<String> protocols = new ArrayList<String>(
|
||||
Arrays.asList(params.getProtocols()));
|
||||
protocols.remove("SSLv2Hello");
|
||||
params.setProtocols(protocols.toArray(new String[protocols.size()]));
|
||||
// Adjust the supported ciphers.
|
||||
ArrayList<String> ciphers = new ArrayList<String>(
|
||||
Arrays.asList(params.getCipherSuites()));
|
||||
ciphers.retainAll(Arrays.asList(
|
||||
"TLS_RSA_WITH_AES_128_CBC_SHA256",
|
||||
"TLS_RSA_WITH_AES_256_CBC_SHA256",
|
||||
"TLS_RSA_WITH_AES_256_CBC_SHA",
|
||||
"TLS_RSA_WITH_AES_128_CBC_SHA",
|
||||
"SSL_RSA_WITH_3DES_EDE_CBC_SHA",
|
||||
"SSL_RSA_WITH_RC4_128_SHA1",
|
||||
"SSL_RSA_WITH_RC4_128_MD5",
|
||||
"TLS_EMPTY_RENEGOTIATION_INFO_SCSV"));
|
||||
params.setCipherSuites(ciphers.toArray(new String[ciphers.size()]));
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
// Send the close_notify alert.
|
||||
ret = SSL_shutdown(ssl);
|
||||
switch (ret) {
|
||||
case 1:
|
||||
// A close_notify alert has already been received.
|
||||
break;
|
||||
case 0:
|
||||
// Wait for the close_notify alert from the peer.
|
||||
ret = SSL_shutdown(ssl);
|
||||
switch (ret) {
|
||||
case 0:
|
||||
fprintf(stderr, "info: second SSL_shutdown returned zero\n");
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
ssl_print_error_and_exit(ssl, "SSL_shutdown 2", ret);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ssl_print_error_and_exit(ssl, "SSL_shutdown 1", ret);
|
||||
}
|
||||
SSL_free(ssl);
|
||||
close(sockfd);
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
SSL_CTX_free(ctx);
|
||||
|
27
modules/ROOT/examples/Features-TLS-OpenSSL-Errors.adoc
Normal file
27
modules/ROOT/examples/Features-TLS-OpenSSL-Errors.adoc
Normal file
|
@ -0,0 +1,27 @@
|
|||
|
||||
static void __attribute__((noreturn))
|
||||
ssl_print_error_and_exit(SSL *ssl, const char *op, int ret)
|
||||
{
|
||||
int subcode = SSL_get_error(ssl, ret);
|
||||
switch (subcode) {
|
||||
case SSL_ERROR_NONE:
|
||||
fprintf(stderr, "error: %s: no error to report\n", op);
|
||||
break;
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
case SSL_ERROR_WANT_X509_LOOKUP:
|
||||
case SSL_ERROR_WANT_CONNECT:
|
||||
case SSL_ERROR_WANT_ACCEPT:
|
||||
fprintf(stderr, "error: %s: invalid blocking state %d\n", op, subcode);
|
||||
break;
|
||||
case SSL_ERROR_SSL:
|
||||
fprintf(stderr, "error: %s: TLS layer problem\n", op);
|
||||
case SSL_ERROR_SYSCALL:
|
||||
fprintf(stderr, "error: %s: system call failed: %s\n", op, strerror(errno));
|
||||
break;
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
fprintf(stderr, "error: %s: zero return\n", op);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
3
modules/ROOT/examples/Features-TLS-Python-Close.adoc
Normal file
3
modules/ROOT/examples/Features-TLS-Python-Close.adoc
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
sock.close()
|
||||
|
4
modules/ROOT/examples/Features-TLS-Python-Use.adoc
Normal file
4
modules/ROOT/examples/Features-TLS-Python-Use.adoc
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
sock.write("GET / HTTP/1.1\r\nHost: " + host + "\r\n\r\n")
|
||||
print sock.read()
|
||||
|
21
modules/ROOT/examples/Go-Error_Handling-IO.adoc
Normal file
21
modules/ROOT/examples/Go-Error_Handling-IO.adoc
Normal file
|
@ -0,0 +1,21 @@
|
|||
|
||||
func IOError(r io.Reader, buf []byte, processor Processor,
|
||||
handler ErrorHandler) (message string, err error) {
|
||||
n, err := r.Read(buf)
|
||||
// First check for available data.
|
||||
if n > 0 {
|
||||
message, err = processor.Process(buf[0:n])
|
||||
// Regular error handling.
|
||||
if err != nil {
|
||||
handler.Handle(err)
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
// Then handle any error.
|
||||
if err != nil {
|
||||
handler.Handle(err)
|
||||
return "", err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
19
modules/ROOT/examples/Go-Error_Handling-Regular.adoc
Normal file
19
modules/ROOT/examples/Go-Error_Handling-Regular.adoc
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
type Processor interface {
|
||||
Process(buf []byte) (message string, err error)
|
||||
}
|
||||
|
||||
type ErrorHandler interface {
|
||||
Handle(err error)
|
||||
}
|
||||
|
||||
func RegularError(buf []byte, processor Processor,
|
||||
handler ErrorHandler) (message string, err error) {
|
||||
message, err = processor.Process(buf)
|
||||
if err != nil {
|
||||
handler.Handle(err)
|
||||
return "", err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
8
modules/ROOT/examples/Java-Finally.adoc
Normal file
8
modules/ROOT/examples/Java-Finally.adoc
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
InputStream in = new BufferedInputStream(new FileInputStream(path));
|
||||
try {
|
||||
readFile(in);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
|
32
modules/ROOT/examples/Java-JNI-Pointers.adoc
Normal file
32
modules/ROOT/examples/Java-JNI-Pointers.adoc
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
JNIEXPORT jint JNICALL Java_sum
|
||||
(JNIEnv *jEnv, jclass clazz, jbyteArray buffer, jint offset, jint length)
|
||||
{
|
||||
assert(sizeof(jint) == sizeof(unsigned));
|
||||
if (offset < 0 || length < 0) {
|
||||
(*jEnv)->ThrowNew(jEnv, arrayIndexOutOfBoundsExceptionClass,
|
||||
"negative offset/length");
|
||||
return 0;
|
||||
}
|
||||
unsigned uoffset = offset;
|
||||
unsigned ulength = length;
|
||||
// This cannot overflow because of the check above.
|
||||
unsigned totallength = uoffset + ulength;
|
||||
unsigned actuallength = (*jEnv)->GetArrayLength(jEnv, buffer);
|
||||
if (totallength > actuallength) {
|
||||
(*jEnv)->ThrowNew(jEnv, arrayIndexOutOfBoundsExceptionClass,
|
||||
"offset + length too large");
|
||||
return 0;
|
||||
}
|
||||
unsigned char *ptr = (*jEnv)->GetPrimitiveArrayCritical(jEnv, buffer, 0);
|
||||
if (ptr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
unsigned long long sum = 0;
|
||||
for (unsigned char *p = ptr + uoffset, *end = p + ulength; p != end; ++p) {
|
||||
sum += *p;
|
||||
}
|
||||
(*jEnv)->ReleasePrimitiveArrayCritical(jEnv, buffer, ptr, 0);
|
||||
return sum;
|
||||
}
|
||||
|
35
modules/ROOT/examples/Java-Language-ReadArray.adoc
Normal file
35
modules/ROOT/examples/Java-Language-ReadArray.adoc
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
static byte[] readBytes(InputStream in, int length) throws IOException {
|
||||
final int startSize = 65536;
|
||||
byte[] b = new byte[Math.min(length, startSize)];
|
||||
int filled = 0;
|
||||
while (true) {
|
||||
int remaining = b.length - filled;
|
||||
readFully(in, b, filled, remaining);
|
||||
if (b.length == length) {
|
||||
break;
|
||||
}
|
||||
filled = b.length;
|
||||
if (length - b.length <= b.length) {
|
||||
// Allocate final length. Condition avoids overflow.
|
||||
b = Arrays.copyOf(b, length);
|
||||
} else {
|
||||
b = Arrays.copyOf(b, b.length * 2);
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
static void readFully(InputStream in,byte[] b, int off, int len)
|
||||
throws IOException {
|
||||
int startlen = len;
|
||||
while (len > 0) {
|
||||
int count = in.read(b, off, len);
|
||||
if (count < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
off += count;
|
||||
len -= count;
|
||||
}
|
||||
}
|
||||
|
36
modules/ROOT/examples/Java-SecurityManager-Callback.adoc
Normal file
36
modules/ROOT/examples/Java-SecurityManager-Callback.adoc
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
interface Callback<T> {
|
||||
T call(boolean flag);
|
||||
}
|
||||
|
||||
class CallbackInvoker<T> {
|
||||
private final AccessControlContext context;
|
||||
Callback<T> callback;
|
||||
|
||||
CallbackInvoker(Callback<T> callback) {
|
||||
context = AccessController.getContext();
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public T invoke() {
|
||||
// Obtain increased privileges.
|
||||
return AccessController.doPrivileged(new PrivilegedAction<T>() {
|
||||
@Override
|
||||
public T run() {
|
||||
// This operation would fail without
|
||||
// additional privileges.
|
||||
final boolean flag = Boolean.getBoolean("some.property");
|
||||
|
||||
// Restore the original privileges.
|
||||
return AccessController.doPrivileged(
|
||||
new PrivilegedAction<T>() {
|
||||
@Override
|
||||
public T run() {
|
||||
return callback.call(flag);
|
||||
}
|
||||
}, context);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
permissions.add(new FilePermission(
|
||||
System.getProperty("user.dir") + "/-", "read"));
|
||||
|
15
modules/ROOT/examples/Java-SecurityManager-Privileged.adoc
Normal file
15
modules/ROOT/examples/Java-SecurityManager-Privileged.adoc
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
// This is expected to fail.
|
||||
try {
|
||||
System.out.println(System.getProperty("user.home"));
|
||||
} catch (SecurityException e) {
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
// This should work.
|
||||
System.out.println(System.getProperty("user.home"));
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
24
modules/ROOT/examples/Java-SecurityManager-Unprivileged.adoc
Normal file
24
modules/ROOT/examples/Java-SecurityManager-Unprivileged.adoc
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
Permissions permissions = new Permissions();
|
||||
ProtectionDomain protectionDomain =
|
||||
new ProtectionDomain(null, permissions);
|
||||
AccessControlContext context = new AccessControlContext(
|
||||
new ProtectionDomain[] { protectionDomain });
|
||||
|
||||
// This is expected to succeed.
|
||||
try (FileInputStream in = new FileInputStream(path)) {
|
||||
System.out.format("FileInputStream: %s%n", in);
|
||||
}
|
||||
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
|
||||
@Override
|
||||
public Void run() throws Exception {
|
||||
// This code runs with reduced privileges and is
|
||||
// expected to fail.
|
||||
try (FileInputStream in = new FileInputStream(path)) {
|
||||
System.out.format("FileInputStream: %s%n", in);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}, context);
|
||||
|
5
modules/ROOT/examples/Java-TryWithResource.adoc
Normal file
5
modules/ROOT/examples/Java-TryWithResource.adoc
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
try (InputStream in = new BufferedInputStream(new FileInputStream(path))) {
|
||||
readFile(in);
|
||||
}
|
||||
|
8
modules/ROOT/examples/Shell-Input_Validation.adoc
Normal file
8
modules/ROOT/examples/Shell-Input_Validation.adoc
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
if [[ $value =~ ^-?[0-9]+$ ]] ; then
|
||||
echo value is an integer
|
||||
else
|
||||
echo "value is not an integer" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
XML_Parser parser = XML_ParserCreate("UTF-8");
|
||||
if (parser == NULL) {
|
||||
fprintf(stderr, "XML_ParserCreate failed\n");
|
||||
close(fd);
|
||||
exit(1);
|
||||
}
|
||||
// EntityDeclHandler needs a reference to the parser to stop
|
||||
// parsing.
|
||||
XML_SetUserData(parser, parser);
|
||||
// Disable entity processing, to inhibit entity expansion.
|
||||
XML_SetEntityDeclHandler(parser, EntityDeclHandler);
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
// Stop the parser when an entity declaration is encountered.
|
||||
static void
|
||||
EntityDeclHandler(void *userData,
|
||||
const XML_Char *entityName, int is_parameter_entity,
|
||||
const XML_Char *value, int value_length,
|
||||
const XML_Char *base, const XML_Char *systemId,
|
||||
const XML_Char *publicId, const XML_Char *notationName)
|
||||
{
|
||||
XML_StopParser((XML_Parser)userData, XML_FALSE);
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
class Errors implements ErrorHandler {
|
||||
@Override
|
||||
public void warning(SAXParseException exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fatalError(SAXParseException exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(SAXParseException exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
import javax.xml.validation.Schema;
|
||||
import javax.xml.validation.SchemaFactory;
|
||||
import javax.xml.validation.Validator;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.ls.LSInput;
|
||||
import org.w3c.dom.ls.LSResourceResolver;
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
import org.xml.sax.XMLReader;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
class NoEntityResolver implements EntityResolver {
|
||||
@Override
|
||||
public InputSource resolveEntity(String publicId, String systemId)
|
||||
throws SAXException, IOException {
|
||||
// Throwing an exception stops validation.
|
||||
throw new IOException(String.format(
|
||||
"attempt to resolve \"%s\" \"%s\"", publicId, systemId));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
class NoResourceResolver implements LSResourceResolver {
|
||||
@Override
|
||||
public LSInput resolveResource(String type, String namespaceURI,
|
||||
String publicId, String systemId, String baseURI) {
|
||||
// Throwing an exception stops validation.
|
||||
throw new RuntimeException(String.format(
|
||||
"resolution attempt: type=%s namespace=%s " +
|
||||
"publicId=%s systemId=%s baseURI=%s",
|
||||
type, namespaceURI, publicId, systemId, baseURI));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
// Impose restrictions on the complexity of the DTD.
|
||||
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||
|
||||
// Turn on validation.
|
||||
// This step can be omitted if validation is not desired.
|
||||
factory.setValidating(true);
|
||||
|
||||
// Parse the document.
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
builder.setEntityResolver(new NoEntityResolver());
|
||||
builder.setErrorHandler(new Errors());
|
||||
Document document = builder.parse(inputStream);
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
SchemaFactory factory = SchemaFactory.newInstance(
|
||||
XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||
|
||||
// This enables restrictions on schema complexity.
|
||||
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||
|
||||
// The following line prevents resource resolution
|
||||
// by the schema itself.
|
||||
factory.setResourceResolver(new NoResourceResolver());
|
||||
|
||||
Schema schema = factory.newSchema(schemaFile);
|
||||
|
||||
Validator validator = schema.newValidator();
|
||||
|
||||
// This prevents external resource resolution.
|
||||
validator.setResourceResolver(new NoResourceResolver());
|
||||
validator.validate(new DOMSource(document));
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
SchemaFactory factory = SchemaFactory.newInstance(
|
||||
XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||
|
||||
// This enables restrictions on the schema and document
|
||||
// complexity.
|
||||
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
|
||||
|
||||
// This prevents resource resolution by the schema itself.
|
||||
// If the schema is trusted and references additional files,
|
||||
// this line must be omitted, otherwise loading these files
|
||||
// will fail.
|
||||
factory.setResourceResolver(new NoResourceResolver());
|
||||
|
||||
Schema schema = factory.newSchema(schemaFile);
|
||||
Validator validator = schema.newValidator();
|
||||
|
||||
// This prevents external resource resolution.
|
||||
validator.setResourceResolver(new NoResourceResolver());
|
||||
|
||||
validator.validate(new SAXSource(new InputSource(inputStream)));
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
class NoEntityHandler : public QXmlDeclHandler {
|
||||
public:
|
||||
bool attributeDecl(const QString&, const QString&, const QString&,
|
||||
const QString&, const QString&);
|
||||
bool internalEntityDecl(const QString&, const QString&);
|
||||
bool externalEntityDecl(const QString&, const QString&,
|
||||
const QString&);
|
||||
QString errorString() const;
|
||||
};
|
||||
|
||||
bool
|
||||
NoEntityHandler::attributeDecl
|
||||
(const QString&, const QString&, const QString&, const QString&,
|
||||
const QString&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
NoEntityHandler::internalEntityDecl(const QString&, const QString&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
NoEntityHandler::externalEntityDecl(const QString&, const QString&, const
|
||||
QString&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QString
|
||||
NoEntityHandler::errorString() const
|
||||
{
|
||||
return "XML declaration not permitted";
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
class NoEntityReader : public QXmlSimpleReader {
|
||||
NoEntityHandler handler;
|
||||
public:
|
||||
NoEntityReader();
|
||||
void setDeclHandler(QXmlDeclHandler *);
|
||||
};
|
||||
|
||||
NoEntityReader::NoEntityReader()
|
||||
{
|
||||
QXmlSimpleReader::setDeclHandler(&handler);
|
||||
setFeature("http://xml.org/sax/features/namespaces", true);
|
||||
setFeature("http://xml.org/sax/features/namespace-prefixes", false);
|
||||
}
|
||||
|
||||
void
|
||||
NoEntityReader::setDeclHandler(QXmlDeclHandler *)
|
||||
{
|
||||
// Ignore the handler which was passed in.
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
NoEntityReader reader;
|
||||
QBuffer buffer(&data);
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
QXmlInputSource source(&buffer);
|
||||
QDomDocument doc;
|
||||
QString errorMsg;
|
||||
int errorLine;
|
||||
int errorColumn;
|
||||
bool okay = doc.setContent
|
||||
(&source, &reader, &errorMsg, &errorLine, &errorColumn);
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue