Update structure for partials and examples

This commit is contained in:
Petr Bokoc 2022-01-13 20:42:40 +01:00
parent b1b3d6a960
commit 531ddf0721
89 changed files with 79 additions and 79 deletions

View 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;
}

View 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;
}

View file

@ -0,0 +1,10 @@
unsigned
mul(unsigned a, unsigned b)
{
if (b && a > ((unsigned)-1) / b) {
report_overflow();
}
return a * b;
}

View file

@ -0,0 +1,8 @@
static const char *const string_list[] = {
"first",
"second",
"third",
NULL
};

View 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;
}

View 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);
}

View file

@ -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);
}

View file

@ -0,0 +1,4 @@
char fraction[30];
snprintf(fraction, sizeof(fraction), "%d/%d", numerator, denominator);

View file

@ -0,0 +1,4 @@
buf[0] = '\0';
strncat(buf, data, sizeof(buf) - 1);

View file

@ -0,0 +1,5 @@
char buf[10];
snprintf(buf, sizeof(buf), "%s", prefix);
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s", data);

View file

@ -0,0 +1,3 @@
snprintf(buf, sizeof(buf), "%s%s", prefix, data);

View file

@ -0,0 +1,5 @@
char buf[10];
strncpy(buf, data, sizeof(buf));
buf[sizeof(buf) - 1] = '\0';

View 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;
}

View 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);

View 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);
}

View 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;
}

View 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);

View file

@ -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);
}

View file

@ -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);
}

View 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);
}
}

View 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);

View 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);
}

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -0,0 +1,3 @@
params.setEndpointIdentificationAlgorithm("HTTPS");

View file

@ -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;

View file

@ -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];
}
}

View file

@ -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);

View 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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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();

View file

@ -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")

View file

@ -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

View file

@ -0,0 +1,3 @@
gnutls_certificate_free_credentials(cred);

View 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);

View file

@ -0,0 +1,5 @@
// This is only necessary if compatibility with GnuTLS prior to
// 3.3.0 is required.
gnutls_global_init();

View 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);
}

View file

@ -0,0 +1,4 @@
SECMOD_DestroyModule(module);
NSS_ShutdownContext(ctx);

View 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);

View 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);
}

View 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);
}

View 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);
}

View 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()]));

View file

@ -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);

View file

@ -0,0 +1,3 @@
SSL_CTX_free(ctx);

View 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);
}

View file

@ -0,0 +1,3 @@
sock.close()

View file

@ -0,0 +1,4 @@
sock.write("GET / HTTP/1.1\r\nHost: " + host + "\r\n\r\n")
print sock.read()

View 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
}

View 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
}

View file

@ -0,0 +1,8 @@
InputStream in = new BufferedInputStream(new FileInputStream(path));
try {
readFile(in);
} finally {
in.close();
}

View 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;
}

View 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;
}
}

View 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);
}
});
}
}

View file

@ -0,0 +1,4 @@
permissions.add(new FilePermission(
System.getProperty("user.dir") + "/-", "read"));

View 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;
}
});

View 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);

View file

@ -0,0 +1,5 @@
try (InputStream in = new BufferedInputStream(new FileInputStream(path))) {
readFile(in);
}

View 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

View file

@ -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);

View file

@ -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);
}

View file

@ -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();
}
}

View file

@ -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;

View file

@ -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));
}
}

View file

@ -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));
}
}

View file

@ -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);

View file

@ -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));

View file

@ -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)));

View file

@ -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";
}

View file

@ -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.
}

View file

@ -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);