Converted to AsciiBinder
This required moving files around in the repository and shifting from a master.adoc structure to _topic_map.yml, etc. README and Makefile modified slightly to reflect new build process
This commit is contained in:
parent
161b3a786e
commit
2e8934be40
186 changed files with 30936 additions and 372 deletions
13
en-US/C.adoc
13
en-US/C.adoc
|
@ -1,13 +0,0 @@
|
|||
|
||||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-C]]
|
||||
=== The C Programming Language
|
||||
|
||||
include::C-Language.adoc[]
|
||||
|
||||
include::C-Libc.adoc[]
|
||||
|
||||
include::C-Allocators.adoc[]
|
||||
|
||||
include::C-Other.adoc[]
|
|
@ -1,9 +0,0 @@
|
|||
|
||||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-CXX]]
|
||||
=== The C++ Programming Language
|
||||
|
||||
include::CXX-Language.adoc[]
|
||||
|
||||
include::CXX-Std.adoc[]
|
|
@ -1,8 +1,6 @@
|
|||
|
||||
:experimental:
|
||||
include::../entities.adoc[]
|
||||
|
||||
Copyright {YEAR} {HOLDER}.
|
||||
Copyright {YEAR} {HOLDER}.
|
||||
|
||||
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at link:++http://creativecommons.org/licenses/by-sa/3.0/++[]. The original authors of this document, and Red Hat, designate the Fedora Project as the "Attribution Party" for purposes of CC-BY-SA. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
|
||||
|
||||
|
@ -20,4 +18,4 @@ For guidelines on the permitted uses of the Fedora trademarks, refer to link:++h
|
|||
|
||||
*MySQL* is a registered trademark of MySQL AB in the United States, the European Union and other countries.
|
||||
|
||||
All other trademarks are the property of their respective owners.
|
||||
All other trademarks are the property of their respective owners.
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-Java]]
|
||||
=== The Java Programming Language
|
||||
|
||||
include::Java-Language.adoc[]
|
||||
|
||||
include::Java-LowLevel.adoc[]
|
||||
|
||||
include::Java-SecurityManager.adoc[]
|
|
@ -2,7 +2,7 @@
|
|||
:experimental:
|
||||
|
||||
[[appe-Defensive_Coding-Revision_History]]
|
||||
== Revision History
|
||||
= Revision History
|
||||
|
||||
`1.5`:: Fri Dec 1 2017, Mirek Jahoda (mjahoda@redhat.com)
|
||||
|
||||
|
@ -57,4 +57,4 @@
|
|||
|
||||
`0-1`:: Thu Mar 7 2013, Eric Christensen (sparks@redhat.com)
|
||||
|
||||
* Initial publication.
|
||||
* Initial publication.
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-Authentication]]
|
||||
=== Authentication and Authorization
|
||||
= Authentication and Authorization
|
||||
|
||||
[[sect-Defensive_Coding-Authentication-Server]]
|
||||
==== Authenticating Servers
|
||||
== Authenticating Servers
|
||||
|
||||
When connecting to a server, a client has to make sure that it
|
||||
is actually talking to the server it expects. There are two
|
||||
|
@ -47,7 +47,7 @@ crashing the real server by exploiting a denial-of-service
|
|||
vulnerability.
|
||||
|
||||
[[sect-Defensive_Coding-Authentication-Host_based]]
|
||||
==== Host-based Authentication
|
||||
== Host-based Authentication
|
||||
|
||||
Host-based authentication uses access control lists (ACLs) to
|
||||
accept or deny requests from clients. This authentication
|
||||
|
@ -92,7 +92,7 @@ universally correct way to deal with this ambiguity. The
|
|||
behavior of the ACL implementation should be documented.
|
||||
|
||||
[[sect-Defensive_Coding-Authentication-UNIX_Domain]]
|
||||
==== UNIX Domain Socket Authentication
|
||||
== UNIX Domain Socket Authentication
|
||||
|
||||
UNIX domain sockets (with address family
|
||||
`AF_UNIX` or `AF_LOCAL`) are
|
||||
|
@ -127,7 +127,7 @@ information from `/proc/PID/status` is prone
|
|||
to race conditions and insecure.
|
||||
|
||||
[[sect-Defensive_Coding-Authentication-Netlink]]
|
||||
==== `AF_NETLINK` Authentication of Origin
|
||||
== `AF_NETLINK` Authentication of Origin
|
||||
|
||||
Netlink messages are used as a high-performance data transfer
|
||||
mechanism between the kernel and the user space. Traditionally,
|
||||
|
@ -148,4 +148,4 @@ address will be non-zero in such cases.
|
|||
|
||||
Applications should not use `AF_NETLINK`
|
||||
sockets as an IPC mechanism among processes, but prefer UNIX
|
||||
domain sockets for this tasks.
|
||||
domain sockets for this tasks.
|
|
@ -2,7 +2,7 @@
|
|||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-HSM]]
|
||||
=== Hardware Security Modules and Smart Cards
|
||||
= Hardware Security Modules and Smart Cards
|
||||
|
||||
Hardware Security Modules (HSMs) are specialized hardware intended
|
||||
to protect private keys on server systems. They store internally
|
||||
|
@ -61,7 +61,7 @@ modules or smart cards. The wrapper PKCS#11 APIs provided by NSS, GnuTLS and
|
|||
engine_pkcs11 (OpenSSL) handle the reinitialization after fork requirement transparently.
|
||||
|
||||
[[sect-Defensive_Coding-HSM-OpenSSL]]
|
||||
==== OpenSSL HSM Support
|
||||
== OpenSSL HSM Support
|
||||
|
||||
OpenSSL does not have native support for PKCS#11. It can
|
||||
provide PKCS#11 support through the OpenSC's project
|
||||
|
@ -81,13 +81,13 @@ and its usage to sign data.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-HSM-OpenSSL.adoc[]
|
||||
include::en-US/snippets/Features-HSM-OpenSSL.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[sect-Defensive_Coding-HSM-GNUTLS]]
|
||||
==== GnuTLS HSM Support
|
||||
== GnuTLS HSM Support
|
||||
|
||||
GnuTLS supports PKCS#11 natively. Most of the API functions
|
||||
accepting certificate files, can also accept PKCS#11 URLs, thus
|
||||
|
@ -104,7 +104,7 @@ and its usage to sign data.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-HSM-GNUTLS.adoc[]
|
||||
include::en-US/snippets/Features-HSM-GNUTLS.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -119,13 +119,13 @@ An example PIN callback function is shown below.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-HSM-GNUTLS-PIN.adoc[]
|
||||
include::en-US/snippets/Features-HSM-GNUTLS-PIN.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[sect-Defensive_Coding-HSM-NSS]]
|
||||
==== NSS HSM Support
|
||||
== NSS HSM Support
|
||||
|
||||
NSS supports PKCS#11 natively. In fact all NSS crypto operations,
|
||||
including built-in operations, go through PKCS #11 modules. NSS provides
|
||||
|
@ -145,7 +145,7 @@ The following example demonstrates a typical NSS application for signing.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-HSM-NSS.adoc[]
|
||||
include::en-US/snippets/Features-HSM-NSS.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -164,7 +164,7 @@ $ modutil -list -dbdir .
|
|||
$ certutil -L -h ${token_name} -d .
|
||||
# pass the cert to your signing program
|
||||
$ NSS_Sign_Example "${token_name}:${cert_name}"
|
||||
|
||||
|
||||
----
|
||||
|
||||
[[ex-Defensive_Coding-HSM-NSS-PIN]]
|
||||
|
@ -173,7 +173,7 @@ $ NSS_Sign_Example "${token_name}:${cert_name}"
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-HSM-NSS-PIN.adoc[]
|
||||
include::en-US/snippets/Features-HSM-NSS-PIN.adoc[]
|
||||
----
|
||||
|
||||
====
|
|
@ -1,9 +1,9 @@
|
|||
|
||||
:experimental:
|
||||
include::entities.adoc[]
|
||||
include::en-US/entities.adoc[]
|
||||
|
||||
[[chap-Defensive_Coding-TLS]]
|
||||
=== Transport Layer Security (TLS)
|
||||
= Transport Layer Security (TLS)
|
||||
|
||||
Transport Layer Security (TLS, formerly Secure Sockets
|
||||
Layer/SSL) is the recommended way to to protect integrity and
|
||||
|
@ -24,7 +24,7 @@ library' documentation.
|
|||
* link:++https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html++[OpenJDK documentation]
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Pitfalls]]
|
||||
==== Common Pitfalls
|
||||
== Common Pitfalls
|
||||
|
||||
TLS implementations are difficult to use, and most of them lack
|
||||
a clean API design. The following sections contain
|
||||
|
@ -62,7 +62,7 @@ duration of the handshake), or use the Linux-specific
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Nagle.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Nagle.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -94,7 +94,7 @@ cannot be used across `fork` function
|
|||
calls (see <<sect-Defensive_Coding-Tasks-Processes-Fork-Parallel>>).
|
||||
|
||||
[[sect-Defensive_Coding-TLS-OpenSSL]]
|
||||
===== OpenSSL Pitfalls
|
||||
=== OpenSSL Pitfalls
|
||||
|
||||
Some OpenSSL function use *tri-state return
|
||||
values*. Correct error checking is extremely
|
||||
|
@ -133,7 +133,7 @@ due to a connection teardown by the other end).
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-OpenSSL-Errors.adoc[]
|
||||
include::en-US/snippets/Features-TLS-OpenSSL-Errors.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -193,14 +193,14 @@ increase the part of the code base which has to undergo
|
|||
security certification.
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Pitfalls-GnuTLS]]
|
||||
===== GnuTLS Pitfalls
|
||||
=== GnuTLS Pitfalls
|
||||
|
||||
Older versions of GnuTLS had several peculiarities described
|
||||
in previous versions of this guide; as of GnuTLS 3.3.10, these
|
||||
issues are no longer applicable.
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Pitfalls-OpenJDK]]
|
||||
===== OpenJDK Pitfalls
|
||||
=== OpenJDK Pitfalls
|
||||
|
||||
The Java cryptographic framework is highly modular. As a
|
||||
result, when you request an object implementing some
|
||||
|
@ -224,7 +224,7 @@ can block, waiting for more bits to become available in
|
|||
`/dev/random`.
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Pitfalls-NSS]]
|
||||
===== NSS Pitfalls
|
||||
=== NSS Pitfalls
|
||||
|
||||
NSS was not designed to be used by other libraries which can
|
||||
be linked into applications without modifying them. There is
|
||||
|
@ -242,7 +242,7 @@ initialized. This behavior is required by the PKCS#11 API
|
|||
specification.
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Client]]
|
||||
==== TLS Clients
|
||||
== TLS Clients
|
||||
|
||||
Secure use of TLS in a client generally involves all of the
|
||||
following steps. (Individual instructions for specific TLS
|
||||
|
@ -295,7 +295,7 @@ client. These aspects are not yet covered.
|
|||
|
||||
====
|
||||
|
||||
===== Implementation TLS Clients With OpenSSL
|
||||
=== Implementation TLS Clients With OpenSSL
|
||||
|
||||
In the following code, the error handling is only exploratory.
|
||||
Proper error handling is required for production use,
|
||||
|
@ -309,7 +309,7 @@ The OpenSSL library needs explicit initialization (see <<ex-Defensive_Coding-TLS
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenSSL-Init.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenSSL-Init.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -332,7 +332,7 @@ be cumbersome.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenSSL-CTX.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenSSL-CTX.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -380,7 +380,7 @@ name.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenSSL-Connect.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenSSL-Connect.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -397,7 +397,7 @@ transport, using `BIO_set_ssl`.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenSSL-Connection-Use.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenSSL-Connection-Use.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -418,7 +418,7 @@ socket after the connection object has been freed.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-OpenSSL-Connection-Close.adoc[]
|
||||
include::en-US/snippets/Features-TLS-OpenSSL-Connection-Close.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -433,13 +433,13 @@ because no further TLS connections will be established.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-OpenSSL-Context-Close.adoc[]
|
||||
include::en-US/snippets/Features-TLS-OpenSSL-Context-Close.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Client-GnuTLS]]
|
||||
===== Implementation TLS Clients With GnuTLS
|
||||
=== Implementation TLS Clients With GnuTLS
|
||||
|
||||
This section describes how to implement a TLS client with full
|
||||
certificate validation (but without certificate revocation
|
||||
|
@ -456,7 +456,7 @@ CAs (<<ex-Defensive_Coding-TLS-Client-GNUTLS-Credentials>>).
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-GNUTLS-Credentials.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-GNUTLS-Credentials.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -466,7 +466,7 @@ object should be freed:
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-GNUTLS-Credentials-Close.adoc[]
|
||||
include::en-US/snippets/Features-TLS-GNUTLS-Credentials-Close.adoc[]
|
||||
----
|
||||
|
||||
During its lifetime, the credentials object can be used to
|
||||
|
@ -486,7 +486,7 @@ This is shown in <<ex-Defensive_Coding-TLS-Client-GNUTLS-Connect>>.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-GNUTLS-Connect.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-GNUTLS-Connect.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -505,7 +505,7 @@ can be omitted if the functionality is not needed.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-GNUTLS-Verify.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-GNUTLS-Verify.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -519,7 +519,7 @@ receiving data, as in <<ex-Defensive_Coding-TLS-GNUTLS-Use>>.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-GNUTLS-Use.adoc[]
|
||||
include::en-US/snippets/Features-TLS-GNUTLS-Use.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -535,20 +535,20 @@ Finally, the session object can be deallocated using
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-GNUTLS-Disconnect.adoc[]
|
||||
include::en-US/snippets/Features-TLS-GNUTLS-Disconnect.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Client-OpenJDK]]
|
||||
===== Implementing TLS Clients With OpenJDK
|
||||
=== Implementing TLS Clients With OpenJDK
|
||||
|
||||
The examples below use the following cryptographic-related
|
||||
classes:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenJDK-Import.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenJDK-Import.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -579,7 +579,7 @@ be supported as a fall-back option. This is shown in <<ex-Defensive_Coding-TLS-C
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenJDK-Context.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenJDK-Context.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -595,7 +595,7 @@ connections.
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-OpenJDK-Parameters.adoc[]
|
||||
include::en-US/snippets/Features-TLS-OpenJDK-Parameters.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -606,7 +606,7 @@ separately, and this is only supported by OpenJDK 7 and later:
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenJDK-Hostname.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenJDK-Hostname.adoc[]
|
||||
----
|
||||
|
||||
All application protocols can use the
|
||||
|
@ -629,7 +629,7 @@ internal API on OpenJDK 6.
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenJDK-Connect.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenJDK-Connect.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -650,12 +650,12 @@ The TLS socket can be used as a regular socket, as shown in
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenJDK-Use.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenJDK-Use.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
====== Overriding server certificate validation with OpenJDK 6
|
||||
==== Overriding server certificate validation with OpenJDK 6
|
||||
|
||||
Overriding certificate validation requires a custom trust
|
||||
manager. With OpenJDK 6, the trust manager lacks
|
||||
|
@ -675,7 +675,7 @@ the server certificate is identified by its SHA-256 hash.
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenJDK-MyTrustManager.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenJDK-MyTrustManager.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -690,7 +690,7 @@ This trust manager has to be passed to the
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-OpenJDK-Context_For_Cert.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-OpenJDK-Context_For_Cert.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -716,7 +716,7 @@ manager object can be used for multiple servers because the
|
|||
server address is available to the trust manager.
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Client-NSS]]
|
||||
===== Implementing TLS Clients With NSS
|
||||
=== Implementing TLS Clients With NSS
|
||||
|
||||
The following code shows how to implement a simple TLS client
|
||||
using NSS. These instructions apply to NSS version 3.14 and
|
||||
|
@ -735,7 +735,7 @@ Using NSS needs several header files, as shown in
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-NSS-Includes.adoc[]
|
||||
include::en-US/snippets/Features-TLS-NSS-Includes.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -761,7 +761,7 @@ load trusted CA certificates from a file.)
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-NSS-Init.adoc[]
|
||||
include::en-US/snippets/Features-TLS-NSS-Init.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -772,7 +772,7 @@ the following function calls:
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-NSS-Close.adoc[]
|
||||
include::en-US/snippets/Features-TLS-NSS-Close.adoc[]
|
||||
----
|
||||
|
||||
After NSS has been initialized, the TLS connection can be
|
||||
|
@ -808,7 +808,7 @@ certificate is verified and matched against the host name.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-NSS-Connect.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-NSS-Connect.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -822,7 +822,7 @@ the NSPR descriptor to communicate with the server.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-NSS-Use.adoc[]
|
||||
include::en-US/snippets/Features-TLS-NSS-Use.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -836,14 +836,14 @@ shows how to close the connection.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-NSS-Close.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-NSS-Close.adoc[]
|
||||
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[sect-Defensive_Coding-TLS-Client-Python]]
|
||||
===== Implementing TLS Clients With Python
|
||||
=== Implementing TLS Clients With Python
|
||||
|
||||
The Python distribution provides a TLS implementation in the
|
||||
`ssl` module (actually a wrapper around
|
||||
|
@ -877,7 +877,7 @@ certificate returned by `getpeercert`.
|
|||
|
||||
[source,python]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-Python-check_host_name.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-Python-check_host_name.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -923,7 +923,7 @@ manually against the host name, by calling the
|
|||
|
||||
[source,python]
|
||||
----
|
||||
include::snippets/Features-TLS-Client-Python-Connect.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Client-Python-Connect.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -933,12 +933,12 @@ be used like a regular socket:
|
|||
|
||||
[source,python]
|
||||
----
|
||||
include::snippets/Features-TLS-Python-Use.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Python-Use.adoc[]
|
||||
----
|
||||
|
||||
Closing the TLS socket is straightforward as well:
|
||||
|
||||
[source,python]
|
||||
----
|
||||
include::snippets/Features-TLS-Python-Close.adoc[]
|
||||
include::en-US/snippets/Features-TLS-Python-Close.adoc[]
|
||||
----
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
|
@ -1,5 +1,5 @@
|
|||
|
||||
:experimental:
|
||||
include::en-US/entities.adoc[]
|
||||
|
||||
A Guide to Improving Software Security
|
||||
|
||||
|
@ -12,7 +12,7 @@ programming languages and libraries, and focuses on
|
|||
concrete recommendations.
|
||||
|
||||
--
|
||||
image:Common_Content/images/title_logo.svg[]
|
||||
include::Common_Content/Legal_Notice.adoc[]
|
||||
image::title_logo.svg[]
|
||||
include::en-US/Common_Content/Legal_Notice.adoc[]
|
||||
|
||||
include::Author_Group.adoc[]
|
||||
include::en-US/Author_Group.adoc[]
|
|
@ -1,54 +0,0 @@
|
|||
:doctype: book
|
||||
:toc: left
|
||||
:toclevels: 3
|
||||
:source-highlighter: pygments
|
||||
:pygments-style: friendly
|
||||
:pygments-linenums-mode: inline
|
||||
|
||||
= Defensive Coding Guide
|
||||
|
||||
include::Book_Info.adoc[]
|
||||
|
||||
== Programming Languages
|
||||
|
||||
include::C.adoc[]
|
||||
|
||||
include::CXX.adoc[]
|
||||
|
||||
include::Java.adoc[]
|
||||
|
||||
include::Python.adoc[]
|
||||
|
||||
include::Shell.adoc[]
|
||||
|
||||
include::Go.adoc[]
|
||||
|
||||
include::Vala.adoc[]
|
||||
|
||||
== Specific Programming Tasks
|
||||
|
||||
include::Tasks-Library_Design.adoc[]
|
||||
|
||||
include::Tasks-Descriptors.adoc[]
|
||||
|
||||
include::Tasks-File_System.adoc[]
|
||||
|
||||
include::Tasks-Temporary_Files.adoc[]
|
||||
|
||||
include::Tasks-Processes.adoc[]
|
||||
|
||||
include::Tasks-Serialization.adoc[]
|
||||
|
||||
include::Tasks-Cryptography.adoc[]
|
||||
|
||||
include::Tasks-Packaging.adoc[]
|
||||
|
||||
== Implementing Security Features
|
||||
|
||||
include::Features-Authentication.adoc[]
|
||||
|
||||
include::Features-TLS.adoc[]
|
||||
|
||||
include::Features-HSM.adoc[]
|
||||
|
||||
include::Revision_History.adoc[]
|
|
@ -2,9 +2,9 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-C-Allocators]]
|
||||
==== Memory Allocators
|
||||
== Memory Allocators
|
||||
|
||||
===== `malloc` and Related Functions
|
||||
=== `malloc` and Related Functions
|
||||
|
||||
The C library interfaces for memory allocation are provided by
|
||||
`malloc`, `free` and
|
||||
|
@ -27,7 +27,7 @@ realloc(ptr, size);` is wrong because the memory
|
|||
pointed to by `ptr` leaks in case of an error.
|
||||
|
||||
[[sect-Defensive_Coding-C-Use-After-Free]]
|
||||
====== Use-after-free errors
|
||||
==== Use-after-free errors
|
||||
|
||||
After `free`, the pointer is invalid.
|
||||
Further pointer dereferences are not allowed (and are usually
|
||||
|
@ -43,7 +43,7 @@ compiler may assume that a comparison between the old and new
|
|||
pointer will always return false, so it is impossible to detect
|
||||
movement this way.
|
||||
|
||||
====== Handling Memory Allocation Errors
|
||||
==== Handling Memory Allocation Errors
|
||||
|
||||
Recovering from out-of-memory errors is often difficult or even
|
||||
impossible. In these cases, `malloc` and
|
||||
|
@ -60,7 +60,7 @@ terminate the process. See
|
|||
for related memory allocation concerns.
|
||||
|
||||
[[sect-Defensive_Coding-C-Allocators-alloca]]
|
||||
===== `alloca` and Other Forms of Stack-based Allocation
|
||||
=== `alloca` and Other Forms of Stack-based Allocation
|
||||
|
||||
Allocation on the stack is risky because stack overflow checking
|
||||
is implicit. There is a guard page at the end of the memory
|
||||
|
@ -106,7 +106,7 @@ function, check if `malloc` had been called,
|
|||
and free the buffer as needed.
|
||||
|
||||
[[sect-Defensive_Coding-C-Allocators-Arrays]]
|
||||
===== Array Allocation
|
||||
=== Array Allocation
|
||||
|
||||
When allocating arrays, it is important to check for overflows.
|
||||
The `calloc` function performs such checks.
|
||||
|
@ -119,7 +119,7 @@ greater than `((size_t) -1) / sizeof(T)`. See
|
|||
<<sect-Defensive_Coding-C-Arithmetic>>.
|
||||
|
||||
[[sect-Defensive_Coding-C-Allocators-Custom]]
|
||||
===== Custom Memory Allocators
|
||||
=== Custom Memory Allocators
|
||||
|
||||
Custom memory allocates come in two forms: replacements for
|
||||
`malloc`, and completely different interfaces
|
||||
|
@ -146,7 +146,7 @@ fragmentation. But often, utilization of individual pools
|
|||
is poor, and external fragmentation increases the overall
|
||||
memory usage.
|
||||
|
||||
===== Conservative Garbage Collection
|
||||
=== Conservative Garbage Collection
|
||||
|
||||
Garbage collection can be an alternative to explicit memory
|
||||
management using `malloc` and
|
|
@ -2,13 +2,13 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-C-Language]]
|
||||
==== The Core Language
|
||||
== The Core Language
|
||||
|
||||
C provides no memory safety. Most recommendations in this section
|
||||
deal with this aspect of the language.
|
||||
|
||||
[[sect-Defensive_Coding-C-Undefined]]
|
||||
===== Undefined Behavior
|
||||
=== Undefined Behavior
|
||||
|
||||
Some C constructs are defined to be undefined by the C standard.
|
||||
This does not only mean that the standard does not describe
|
||||
|
@ -28,7 +28,7 @@ Common sources of undefined behavior are:
|
|||
* overflow in signed integer arithmetic
|
||||
|
||||
[[sect-Defensive_Coding-C-Pointers]]
|
||||
===== Recommendations for Pointers and Array Handling
|
||||
=== Recommendations for Pointers and Array Handling
|
||||
|
||||
Always keep track of the size of the array you are working with.
|
||||
Often, code is more obviously correct when you keep a pointer
|
||||
|
@ -56,7 +56,7 @@ The cast silences a compiler warning;
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-Pointers-remaining.adoc[]
|
||||
include::../snippets/C-Pointers-remaining.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -74,7 +74,7 @@ because the expression on the left can overflow or wrap around
|
|||
no longer reflects the number of bytes to be processed.
|
||||
|
||||
[[sect-Defensive_Coding-C-Arithmetic]]
|
||||
===== Recommendations for Integer Arithmetic
|
||||
=== Recommendations for Integer Arithmetic
|
||||
|
||||
Overflow in signed integer arithmetic is undefined. This means
|
||||
that it is not possible to check for overflow after it happened,
|
||||
|
@ -86,7 +86,7 @@ see <<ex-Defensive_Coding-C-Arithmetic-bad>>.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-Arithmetic-add.adoc[]
|
||||
include::../snippets/C-Arithmetic-add.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -113,7 +113,7 @@ additions have to be checked in this way.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-Arithmetic-add_unsigned.adoc[]
|
||||
include::../snippets/C-Arithmetic-add_unsigned.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -129,7 +129,7 @@ see <<ex-Defensive_Coding-C-Arithmetic-mult>>.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-Arithmetic-mult.adoc[]
|
||||
include::../snippets/C-Arithmetic-mult.adoc[]
|
||||
----
|
||||
|
||||
====
|
||||
|
@ -169,7 +169,7 @@ semantics for integer arithmetic, including defined behavior on
|
|||
integer overflow.
|
||||
|
||||
[[sect-Defensive_Coding-C-Globals]]
|
||||
===== Global Variables
|
||||
=== Global Variables
|
||||
|
||||
Global variables should be avoided because they usually lead to
|
||||
thread safety hazards. In any case, they should be declared
|
||||
|
@ -189,7 +189,7 @@ after the `*`, and not before it.
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-Globals-String_Array.adoc[]
|
||||
include::../snippets/C-Globals-String_Array.adoc[]
|
||||
|
||||
----
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
:experimental:
|
||||
|
||||
include::entities.adoc[]
|
||||
include::en-US/entities.adoc[]
|
||||
|
||||
[[sect-Defensive_Coding-C-Libc]]
|
||||
==== The C Standard Library
|
||||
== The C Standard Library
|
||||
|
||||
Parts of the C standard library (and the UNIX and GNU extensions)
|
||||
are difficult to use, so you should avoid them.
|
||||
|
@ -15,7 +15,7 @@ buffers using `malloc` which your code must
|
|||
deallocate explicitly using `free`.
|
||||
|
||||
[[sect-Defensive_Coding-C-Absolutely-Banned]]
|
||||
===== Absolutely Banned Interfaces
|
||||
=== Absolutely Banned Interfaces
|
||||
|
||||
The functions listed below must not be used because they are
|
||||
almost always unsafe. Use the indicated replacements instead.
|
||||
|
@ -58,7 +58,7 @@ statvfs` (limit not actually enforced by the kernel,
|
|||
see `_PC_NAME_MAX` above)
|
||||
|
||||
[[sect-Defensive_Coding-C-Avoid]]
|
||||
===== Functions to Avoid
|
||||
=== Functions to Avoid
|
||||
|
||||
The following string manipulation functions can be used securely
|
||||
in principle, but their use should be avoided because they are
|
||||
|
@ -109,7 +109,7 @@ explicit `envp` argument in process creation
|
|||
(see <<sect-Defensive_Coding-Tasks-Processes-environ>>)
|
||||
|
||||
[[sect-Defensive_Coding-C-String-Functions-Length]]
|
||||
===== String Functions with Explicit Length Arguments
|
||||
=== String Functions with Explicit Length Arguments
|
||||
|
||||
The C run-time library provides string manipulation functions
|
||||
which not just look for NUL characters for string termination,
|
||||
|
@ -118,7 +118,7 @@ However, these functions evolved over a long period of time, and
|
|||
the lengths mean different things depending on the function.
|
||||
|
||||
[[sect-Defensive_Coding-C-Libc-snprintf]]
|
||||
====== `snprintf`
|
||||
==== `snprintf`
|
||||
|
||||
The `snprintf` function provides a way to
|
||||
construct a string in a statically-sized buffer. (If the buffer
|
||||
|
@ -127,7 +127,7 @@ size is allocated on the heap, consider use
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-String-Functions-snprintf.adoc[]
|
||||
include::../snippets/C-String-Functions-snprintf.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -157,7 +157,7 @@ invariant. After the loop, the result string is in the
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-String-Functions-snprintf-incremental.adoc[]
|
||||
include::../snippets/C-String-Functions-snprintf-incremental.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -176,7 +176,7 @@ Note that it is not permitted to use the same buffer both as
|
|||
the destination and as a source argument.
|
||||
|
||||
[[sect-Defensive_Coding-C-Libc-vsnprintf]]
|
||||
====== `vsnprintf` and Format Strings
|
||||
==== `vsnprintf` and Format Strings
|
||||
|
||||
If you use `vsnprintf` (or
|
||||
`vasprintf` or even
|
||||
|
@ -192,14 +192,14 @@ function (see <<ex-Defensive_Coding-C-String-Functions-format-Attribute>>).
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-String-Functions-format.adoc[]
|
||||
include::../snippets/C-String-Functions-format.adoc[]
|
||||
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[sect-Defensive_Coding-C-Libc-strncpy]]
|
||||
====== `strncpy`
|
||||
==== `strncpy`
|
||||
|
||||
The `strncpy` function does not ensure that
|
||||
the target buffer is null-terminated. A common idiom for
|
||||
|
@ -207,7 +207,7 @@ ensuring NUL termination is:
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-String-Functions-strncpy.adoc[]
|
||||
include::../snippets/C-String-Functions-strncpy.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -216,12 +216,12 @@ function for this purpose:
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-String-Functions-strncat-as-strncpy.adoc[]
|
||||
include::../snippets/C-String-Functions-strncat-as-strncpy.adoc[]
|
||||
|
||||
----
|
||||
|
||||
[[sect-Defensive_Coding-C-Libc-strncat]]
|
||||
====== `strncat`
|
||||
==== `strncat`
|
||||
|
||||
The length argument of the `strncat`
|
||||
function specifies the maximum number of characters copied
|
||||
|
@ -239,7 +239,7 @@ approach similar to <<ex-Defensive_Coding-C-String-Functions-snprintf-incrementa
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-String-Functions-strncat-emulation.adoc[]
|
||||
include::../snippets/C-String-Functions-strncat-emulation.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -249,7 +249,7 @@ string:
|
|||
|
||||
[source,c]
|
||||
----
|
||||
include::snippets/C-String-Functions-strncat-merged.adoc[]
|
||||
include::../snippets/C-String-Functions-strncat-merged.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -262,7 +262,7 @@ It is not possible to use format strings like
|
|||
you use separate buffers. `snprintf` does
|
||||
not support overlapping source and target strings.
|
||||
|
||||
====== `strlcpy` and `strlcat`
|
||||
==== `strlcpy` and `strlcat`
|
||||
|
||||
Some systems support `strlcpy` and
|
||||
`strlcat` functions which behave this way,
|
||||
|
@ -275,12 +275,12 @@ related to the `snprintf` return value.
|
|||
To emulate `strlcat`, use the approach
|
||||
described in <<sect-Defensive_Coding-C-Libc-strncat>>.
|
||||
|
||||
====== ISO C11 Annex K *pass:attributes[{blank}]`_s` functions
|
||||
==== ISO C11 Annex K *pass:attributes[{blank}]`_s` functions
|
||||
|
||||
ISO C11 adds another set of length-checking functions, but GNU
|
||||
libc currently does not implement them.
|
||||
|
||||
====== Other `strn*` and `stpn*` functions
|
||||
==== Other `strn*` and `stpn*` functions
|
||||
|
||||
GNU libc contains additional functions with different variants
|
||||
of length checking. Consult the documentation before using
|
|
@ -2,10 +2,10 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-C-Other]]
|
||||
==== Other C-related Topics
|
||||
== Other C-related Topics
|
||||
|
||||
[[sect-Defensive_Coding-C-Wrapper-Functions]]
|
||||
===== Wrapper Functions
|
||||
=== Wrapper Functions
|
||||
|
||||
Some libraries provide wrappers for standard library functions.
|
||||
Common cases include allocation functions such as
|
||||
|
@ -50,4 +50,4 @@ For other attributes (such as `malloc`),
|
|||
careful analysis and comparison with the compiler documentation
|
||||
is required to check if propagating the attribute is
|
||||
appropriate. Incorrectly applied attributes can result in
|
||||
undesired behavioral changes in the compiled code.
|
||||
undesired behavioral changes in the compiled code.
|
13
en-US/programming-languages/C.adoc
Normal file
13
en-US/programming-languages/C.adoc
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-C]]
|
||||
= The C Programming Language
|
||||
|
||||
include::en-US/programming-languages/C-Language.adoc[]
|
||||
|
||||
include::en-US/programming-languages/C-Libc.adoc[]
|
||||
|
||||
include::en-US/programming-languages/C-Allocators.adoc[]
|
||||
|
||||
include::en-US/programming-languages/C-Other.adoc[]
|
|
@ -2,12 +2,12 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Language]]
|
||||
==== The Core Language
|
||||
== The Core Language
|
||||
|
||||
C++ includes a large subset of the C language. As far as the C
|
||||
subset is used, the recommendations in <<chap-Defensive_Coding-C>> apply.
|
||||
|
||||
===== Array Allocation with `operator new[]`
|
||||
=== Array Allocation with `operator new[]`
|
||||
|
||||
For very large values of `n`, an expression
|
||||
like `new T[n]` can return a pointer to a heap
|
||||
|
@ -43,7 +43,7 @@ untrusted data.
|
|||
See <<sect-Defensive_Coding-C-Allocators-Arrays>>
|
||||
for array allocation advice for C-style memory allocation.
|
||||
|
||||
===== Overloading
|
||||
=== Overloading
|
||||
|
||||
Do not overload functions with versions that have different
|
||||
security characteristics. For instance, do not implement a
|
||||
|
@ -51,7 +51,7 @@ function `strcat` which works on
|
|||
`std::string` arguments. Similarly, do not name
|
||||
methods after such functions.
|
||||
|
||||
===== ABI compatibility and preparing for security updates
|
||||
=== ABI compatibility and preparing for security updates
|
||||
|
||||
A stable binary interface (ABI) is vastly preferred for security
|
||||
updates. Without a stable ABI, all reverse dependencies need
|
||||
|
@ -81,7 +81,7 @@ Compatibility Issues With {cpp}]
|
|||
pointer-to-implementation idiom).
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Language-CXX11]]
|
||||
===== {cpp}0X and {cpp}11 Support
|
||||
=== {cpp}0X and {cpp}11 Support
|
||||
|
||||
GCC offers different language compatibility modes:
|
||||
|
|
@ -2,19 +2,19 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Std]]
|
||||
==== The C++ Standard Library
|
||||
== The C++ Standard Library
|
||||
|
||||
The C++ standard library includes most of its C counterpart
|
||||
by reference, see <<sect-Defensive_Coding-C-Libc>>.
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Std-Functions]]
|
||||
===== Functions That Are Difficult to Use
|
||||
=== Functions That Are Difficult to Use
|
||||
|
||||
This section collects functions and function templates which are
|
||||
part of the standard library and are difficult to use.
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators]]
|
||||
====== Unpaired Iterators
|
||||
==== Unpaired Iterators
|
||||
|
||||
Functions which use output operators or iterators which do not
|
||||
come in pairs (denoting ranges) cannot perform iterator range
|
||||
|
@ -69,7 +69,7 @@ read beyond the end of the input range if the caller is not careful:
|
|||
* `std::mismatch`
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Std-String]]
|
||||
===== String Handling with `std::string`
|
||||
=== String Handling with `std::string`
|
||||
|
||||
The `std::string` class provides a convenient
|
||||
way to handle strings. Unlike C strings,
|
||||
|
@ -142,7 +142,7 @@ does not depend on sharing of the internal character array
|
|||
object anymore.
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Std-Subscript]]
|
||||
===== Containers and `operator[]`
|
||||
=== Containers and `operator[]`
|
||||
|
||||
Many sequence containers similar to `std::vector`
|
||||
provide both `operator[](size_type)` and a
|
||||
|
@ -169,7 +169,7 @@ defined; it returns an arbitrary pointer, but not necessarily
|
|||
the NULL pointer.
|
||||
|
||||
[[sect-Defensive_Coding-CXX-Std-Iterators]]
|
||||
===== Iterators
|
||||
=== Iterators
|
||||
|
||||
Iterators do not perform any bounds checking. Therefore, all
|
||||
functions that work on iterators should accept them in pairs,
|
8
en-US/programming-languages/CXX.adoc
Normal file
8
en-US/programming-languages/CXX.adoc
Normal file
|
@ -0,0 +1,8 @@
|
|||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-CXX]]
|
||||
= The C++ Programming Language
|
||||
|
||||
include::en-US/programming-languages/CXX-Language.adoc[]
|
||||
|
||||
include::en-US/programming-languages/CXX-Std.adoc[]
|
|
@ -2,12 +2,12 @@
|
|||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-Go]]
|
||||
=== The Go Programming Language
|
||||
= The Go Programming Language
|
||||
|
||||
This chapter contains language-specific recommendations for Go.
|
||||
|
||||
[[chap-Defensive_Coding-Go-Memory_Safety]]
|
||||
==== Memory Safety
|
||||
== Memory Safety
|
||||
|
||||
Go provides memory safety, but only if the program is not executed
|
||||
in parallel (that is, `GOMAXPROCS` is not larger than
|
||||
|
@ -28,7 +28,7 @@ finalizers are executed concurrently, potentially interleaved with
|
|||
the rest of the program.
|
||||
|
||||
[[chap-Defensive_Coding-Go-Error_Handling]]
|
||||
==== Error Handling
|
||||
== Error Handling
|
||||
|
||||
Only a few common operations (such as pointer dereference, integer
|
||||
division, array subscripting) trigger exceptions in Go, called
|
||||
|
@ -53,7 +53,7 @@ details.
|
|||
|
||||
[source,go]
|
||||
----
|
||||
include::snippets/Go-Error_Handling-Regular.adoc[]
|
||||
include::../snippets/Go-Error_Handling-Regular.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -73,14 +73,14 @@ returning both data and an error at the same time.
|
|||
|
||||
[source,go]
|
||||
----
|
||||
include::snippets/Go-Error_Handling-IO.adoc[]
|
||||
include::../snippets/Go-Error_Handling-IO.adoc[]
|
||||
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[chap-Defensive_Coding-Go-Garbage_Collector]]
|
||||
==== Garbage Collector
|
||||
== Garbage Collector
|
||||
|
||||
Older Go releases (before Go 1.3) use a conservative garbage
|
||||
collector without blacklisting. This means that data blobs can
|
||||
|
@ -92,7 +92,7 @@ may be possible to trigger it deliberately—it is unlikely to occur
|
|||
spontaneously.
|
||||
|
||||
[[chap-Defensive_Coding-Go-Marshaling]]
|
||||
==== Marshaling and Unmarshaling
|
||||
== Marshaling and Unmarshaling
|
||||
|
||||
Several packages in the `encoding` hierarchy
|
||||
provide support for serialization and deserialization. The usual
|
|
@ -2,7 +2,7 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-Java-Language]]
|
||||
==== The Core Language
|
||||
== The Core Language
|
||||
|
||||
Implementations of the Java programming language provide strong
|
||||
memory safety, even in the presence of data races in concurrent
|
||||
|
@ -11,7 +11,7 @@ from occurring, unless certain low-level features are used; see
|
|||
<<sect-Defensive_Coding-Java-LowLevel>>.
|
||||
|
||||
[[sect-Defensive_Coding-Java-Language-ReadArray]]
|
||||
===== Increasing Robustness when Reading Arrays
|
||||
=== Increasing Robustness when Reading Arrays
|
||||
|
||||
External data formats often include arrays, and the data is
|
||||
stored as an integer indicating the number of array elements,
|
||||
|
@ -31,7 +31,7 @@ data, implementing an exponential growth policy. See the
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-Language-ReadArray.adoc[]
|
||||
include::../snippets/Java-Language-ReadArray.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -42,7 +42,7 @@ default constructor and do not specify a size hint. You can
|
|||
simply add the elements to the collection as you read them.
|
||||
|
||||
[[sect-Defensive_Coding-Java-Language-Resources]]
|
||||
===== Resource Management
|
||||
=== Resource Management
|
||||
|
||||
Unlike C++, Java does not offer destructors which can deallocate
|
||||
resources in a predictable fashion. All resource management has
|
||||
|
@ -62,7 +62,7 @@ possible and should not throw any exceptions.
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-Finally.adoc[]
|
||||
include::../snippets/Java-Finally.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -87,7 +87,7 @@ used instead. The Java compiler will automatically insert the
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-TryWithResource.adoc[]
|
||||
include::../snippets/Java-TryWithResource.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -109,7 +109,7 @@ unchecked) exceptions, but this should not be a reason to ignore
|
|||
any actual error conditions.
|
||||
|
||||
[[sect-Defensive_Coding-Java-Language-Finalizers]]
|
||||
===== Finalizers
|
||||
=== Finalizers
|
||||
|
||||
Finalizers can be used a last-resort approach to free resources
|
||||
which would otherwise leak. Finalization is unpredictable,
|
||||
|
@ -157,7 +157,7 @@ implemented by overriding the `finalize()`
|
|||
method, and to custom finalization using reference queues.
|
||||
|
||||
[[sect-Defensive_Coding-Java-Language-Exceptions]]
|
||||
===== Recovering from Exceptions and Errors
|
||||
=== Recovering from Exceptions and Errors
|
||||
|
||||
Java exceptions come in three kinds, all ultimately deriving
|
||||
from `java.lang.Throwable`:
|
||||
|
@ -202,7 +202,7 @@ to predict and can happen at any point and reflect that
|
|||
something went wrong beyond all expectations.
|
||||
|
||||
[[sect-Defensive_Coding-Java-Language-Exceptions-Errors]]
|
||||
====== The Difficulty of Catching Errors
|
||||
==== The Difficulty of Catching Errors
|
||||
|
||||
Errors (that is, exceptions which do not (indirectly) derive
|
||||
from `java.lang.Exception`), have the
|
|
@ -2,10 +2,10 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-Java-LowLevel]]
|
||||
==== Low-level Features of the Virtual Machine
|
||||
== Low-level Features of the Virtual Machine
|
||||
|
||||
[[sect-Defensive_Coding-Java-Reflection]]
|
||||
===== Reflection and Private Parts
|
||||
=== Reflection and Private Parts
|
||||
|
||||
The `setAccessible(boolean)` method of the
|
||||
`java.lang.reflect.AccessibleObject` class
|
||||
|
@ -24,7 +24,7 @@ not happen because all the language-defined checks still apply.)
|
|||
This feature should be avoided if possible.
|
||||
|
||||
[[sect-Defensive_Coding-Java-JNI]]
|
||||
===== Java Native Interface (JNI)
|
||||
=== Java Native Interface (JNI)
|
||||
|
||||
The Java Native Interface allows calling from Java code
|
||||
functions specifically written for this purpose, usually in C or
|
||||
|
@ -75,7 +75,7 @@ beginning of the array.
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-JNI-Pointers.adoc[]
|
||||
include::../snippets/Java-JNI-Pointers.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -133,7 +133,7 @@ is defined, but in C/C++ it is not (for the
|
|||
`jint` and `jlong` types).
|
||||
|
||||
[[sect-Defensive_Coding-Java-MiscUnsafe]]
|
||||
===== `sun.misc.Unsafe`
|
||||
=== `sun.misc.Unsafe`
|
||||
|
||||
The `sun.misc.Unsafe` class is unportable and
|
||||
contains many functions explicitly designed to break Java memory
|
|
@ -2,7 +2,7 @@
|
|||
:experimental:
|
||||
|
||||
[[sect-Defensive_Coding-Java-SecurityManager]]
|
||||
==== Interacting with the Security Manager
|
||||
== Interacting with the Security Manager
|
||||
|
||||
The Java platform is largely implemented in the Java language
|
||||
itself. Therefore, within the same JVM, code runs which is part
|
||||
|
@ -38,7 +38,7 @@ default (including many classes which are part of the OpenJDK
|
|||
implementation).
|
||||
|
||||
[[sect-Defensive_Coding-Java-SecurityManager-Compatible]]
|
||||
===== Security Manager Compatibility
|
||||
=== Security Manager Compatibility
|
||||
|
||||
A lot of code can run without any additional permissions at all,
|
||||
with little changes. The following guidelines should help to
|
||||
|
@ -61,7 +61,7 @@ untrusted code (hopefully in a restricted and secure manner),
|
|||
see <<sect-Defensive_Coding-Java-SecurityManager-Privileged>>.
|
||||
|
||||
[[sect-Defensive_Coding-Java-SecurityManager-Activate]]
|
||||
===== Activating the Security Manager
|
||||
=== Activating the Security Manager
|
||||
|
||||
The usual command to launch a Java application,
|
||||
[command]`java`, does not activate the security manager.
|
||||
|
@ -87,7 +87,7 @@ option).
|
|||
----
|
||||
|
||||
grant {
|
||||
permission java.security.AllPermission;
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
|
||||
----
|
||||
|
@ -99,7 +99,7 @@ active, and explicit requests to drop privileges will be
|
|||
honored.
|
||||
|
||||
[[sect-Defensive_Coding-Java-SecurityManager-Unprivileged]]
|
||||
===== Reducing Trust in Code
|
||||
=== Reducing Trust in Code
|
||||
|
||||
The <<ex-Defensive_Coding-Java-SecurityManager-Unprivileged>> example
|
||||
shows how to run a piece code of with reduced privileges.
|
||||
|
@ -110,7 +110,7 @@ shows how to run a piece code of with reduced privileges.
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-SecurityManager-Unprivileged.adoc[]
|
||||
include::../snippets/Java-SecurityManager-Unprivileged.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -123,7 +123,7 @@ on all files in the current directory) can be used:
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-SecurityManager-CurrentDirectory.adoc[]
|
||||
include::../snippets/Java-SecurityManager-CurrentDirectory.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -159,7 +159,7 @@ Unfortunately, this affects the virtual machine as a whole, so
|
|||
it is not possible to do this from a library.
|
||||
|
||||
[[sect-Defensive_Coding-Java-SecurityManager-Privileged]]
|
||||
===== Re-gaining Privileges
|
||||
=== Re-gaining Privileges
|
||||
|
||||
Ordinarily, when trusted code is called from untrusted code, it
|
||||
loses its privileges (because of the untrusted stack frames
|
||||
|
@ -208,7 +208,7 @@ shows how to request additional privileges.
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-SecurityManager-Privileged.adoc[]
|
||||
include::../snippets/Java-SecurityManager-Privileged.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -249,7 +249,7 @@ invocation out of the privileged code section, of course.)
|
|||
|
||||
[source,java]
|
||||
----
|
||||
include::snippets/Java-SecurityManager-Callback.adoc[]
|
||||
include::../snippets/Java-SecurityManager-Callback.adoc[]
|
||||
|
||||
----
|
||||
|
11
en-US/programming-languages/Java.adoc
Normal file
11
en-US/programming-languages/Java.adoc
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-Java]]
|
||||
= The Java Programming Language
|
||||
|
||||
include::en-US/programming-languages/Java-Language.adoc[]
|
||||
|
||||
include::en-US/programming-languages/Java-LowLevel.adoc[]
|
||||
|
||||
include::en-US/programming-languages/Java-SecurityManager.adoc[]
|
|
@ -2,7 +2,7 @@
|
|||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-Python]]
|
||||
=== The Python Programming Language
|
||||
= The Python Programming Language
|
||||
|
||||
Python provides memory safety by default, so low-level security
|
||||
vulnerabilities are rare and typically needs fixing the Python
|
||||
|
@ -19,14 +19,14 @@ particular <<sect-Defensive_Coding-Tasks-Serialization-Library>>
|
|||
|
||||
* <<sect-Defensive_Coding-Tasks-Cryptography-Randomness>>
|
||||
|
||||
==== Dangerous Standard Library Features
|
||||
== Dangerous Standard Library Features
|
||||
|
||||
Some areas of the standard library, notably the
|
||||
`ctypes` module, do not provide memory safety
|
||||
guarantees comparable to the rest of Python. If such
|
||||
functionality is used, the advice in <<sect-Defensive_Coding-C-Language>> should be followed.
|
||||
|
||||
==== Run-time Compilation and Code Generation
|
||||
== Run-time Compilation and Code Generation
|
||||
|
||||
The following Python functions and statements related to code
|
||||
execution should be avoided:
|
||||
|
@ -44,8 +44,8 @@ If you need to parse integers or floating point values, use the
|
|||
functions instead of `eval`. Sandboxing
|
||||
untrusted Python code does not work reliably.
|
||||
|
||||
==== Sandboxing
|
||||
== Sandboxing
|
||||
|
||||
The `rexec` Python module cannot safely sandbox
|
||||
untrusted code and should not be used. The standard CPython
|
||||
implementation is not suitable for sandboxing.
|
||||
implementation is not suitable for sandboxing.
|
|
@ -1,9 +1,9 @@
|
|||
|
||||
:experimental:
|
||||
include::entities.adoc[]
|
||||
include::en-US/entities.adoc[]
|
||||
|
||||
[[chap-Defensive_Coding-Shell]]
|
||||
=== Shell Programming and [application]*bash*
|
||||
= Shell Programming and [application]*bash*
|
||||
|
||||
This chapter contains advice about shell programming, specifically
|
||||
in [application]*bash*. Most of the advice will apply
|
||||
|
@ -12,7 +12,7 @@ integer or array variables have been implemented there as well, with
|
|||
comparable syntax.
|
||||
|
||||
[[sect-Defensive_Coding-Shell-Alternatives]]
|
||||
==== Consider Alternatives
|
||||
== Consider Alternatives
|
||||
|
||||
Once a shell script is so complex that advice in this chapter
|
||||
applies, it is time to step back and consider the question: Is
|
||||
|
@ -25,7 +25,7 @@ offers richer data structures, with less arcane syntax and more
|
|||
consistent behavior.
|
||||
|
||||
[[sect-Defensive_Coding-Shell-Language]]
|
||||
==== Shell Language Features
|
||||
== Shell Language Features
|
||||
|
||||
The following sections cover subtleties concerning the shell
|
||||
programming languages. They have been written with the
|
||||
|
@ -38,7 +38,7 @@ implementations, so they now have to be considered part of the shell
|
|||
programming language.
|
||||
|
||||
[[sect-Defensive_Coding-Shell-Parameter_Expansion]]
|
||||
===== Parameter Expansion
|
||||
=== Parameter Expansion
|
||||
|
||||
The mechanism by which named shell variables and parameters are
|
||||
expanded is called *parameter expansion*. The
|
||||
|
@ -53,7 +53,7 @@ double quotation marks `"`pass:attributes[{blank}]…pass:attributes[{blank}]`"`
|
|||
----
|
||||
|
||||
external-program "$arg1" "$arg2"
|
||||
|
||||
|
||||
----
|
||||
|
||||
If the double quotation marks are omitted, the value of the
|
||||
|
@ -69,7 +69,7 @@ trigger arithmetic evaluation, which can result in code execution.
|
|||
See <<sect-Defensive_Coding-Shell-Arithmetic>>.
|
||||
|
||||
[[sect-Defensive_Coding-Shell-Double_Expansion]]
|
||||
===== Double Expansion
|
||||
=== Double Expansion
|
||||
|
||||
*Double expansion* occurs when, during the
|
||||
expansion of a shell variable, not just the variable is expanded,
|
||||
|
@ -95,7 +95,7 @@ The following sections give examples of places where implicit
|
|||
double expansion occurs.
|
||||
|
||||
[[sect-Defensive_Coding-Shell-Arithmetic]]
|
||||
====== Arithmetic Evaluation
|
||||
==== Arithmetic Evaluation
|
||||
|
||||
*Arithmetic evaluation* is a process by which
|
||||
the shell computes the integer value of an expression specified
|
||||
|
@ -179,7 +179,7 @@ If it is impossible to avoid shell arithmetic on untrusted
|
|||
inputs, refer to <<sect-Defensive_Coding-Shell-Input_Validation>>.
|
||||
|
||||
[[sect-Defensive_Coding-Shell-Types]]
|
||||
====== Type declarations
|
||||
==== Type declarations
|
||||
|
||||
[application]*bash* supports explicit type
|
||||
declarations for shell variables:
|
||||
|
@ -202,7 +202,7 @@ declarations for shell variables:
|
|||
readonly -i integer_variable
|
||||
readonly -a array_variable
|
||||
readonly -A assoc_array_variable
|
||||
|
||||
|
||||
----
|
||||
|
||||
Variables can also be declared as arrays by assigning them an
|
||||
|
@ -212,7 +212,7 @@ array expression, as in:
|
|||
----
|
||||
|
||||
array_variable=(1 2 3 4)
|
||||
|
||||
|
||||
----
|
||||
|
||||
Some built-ins (such as `mapfile`) can
|
||||
|
@ -228,7 +228,7 @@ Shell scripts which use integer or array variables should be
|
|||
rewritten in another, more suitable language. Se <<sect-Defensive_Coding-Shell-Alternatives>>.
|
||||
|
||||
[[sect-Defensive_Coding-Shell-Obscure]]
|
||||
===== Other Obscurities
|
||||
=== Other Obscurities
|
||||
|
||||
Obscure shell language features should not be used. Examples are:
|
||||
|
||||
|
@ -245,7 +245,7 @@ with shell functions.
|
|||
tokenize strings.
|
||||
|
||||
[[sect-Defensive_Coding-Shell-Invoke]]
|
||||
==== Invoking External Commands
|
||||
== Invoking External Commands
|
||||
|
||||
When passing shell variables as single command line arguments,
|
||||
they should always be surrounded by double quotes. See
|
||||
|
@ -300,7 +300,7 @@ See <<sect-Defensive_Coding-Tasks-Processes-Creation>>
|
|||
for additional details on creating child processes.
|
||||
|
||||
[[sect-Defensive_Coding-Shell-Temporary_Files]]
|
||||
==== Temporary Files
|
||||
== Temporary Files
|
||||
|
||||
Temporary files should be created with the
|
||||
`mktemp` command, and temporary directories with
|
||||
|
@ -322,17 +322,17 @@ variables.
|
|||
tmpfile="$(mktemp)"
|
||||
|
||||
cleanup () {
|
||||
rm -f -- "$tmpfile"
|
||||
rm -f -- "$tmpfile"
|
||||
}
|
||||
|
||||
trap cleanup 0
|
||||
|
||||
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
[[sect-Defensive_Coding-Shell-Input_Validation]]
|
||||
==== Performing Input Validation
|
||||
== Performing Input Validation
|
||||
|
||||
In some cases, input validation cannot be avoided. For example,
|
||||
if arithmetic evaluation is absolutely required, it is imperative
|
||||
|
@ -350,7 +350,7 @@ POSIX shells.
|
|||
|
||||
[source,bash]
|
||||
----
|
||||
include::snippets/Shell-Input_Validation.adoc[]
|
||||
include::../snippets/Shell-Input_Validation.adoc[]
|
||||
|
||||
----
|
||||
|
||||
|
@ -366,7 +366,7 @@ results (e.g., if the value being checked contains operators
|
|||
itself) and should not be used.
|
||||
|
||||
[[sect-Defensive_Coding-Shell-Edit_Guard]]
|
||||
==== Guarding Shell Scripts Against Changes
|
||||
== Guarding Shell Scripts Against Changes
|
||||
|
||||
[application]*bash* only reads a shell script up to
|
||||
the point it is needed for executed the next command. This means
|
||||
|
@ -387,7 +387,7 @@ this syntax:
|
|||
----
|
||||
|
||||
main "$@" ; exit $?
|
||||
|
||||
|
||||
----
|
||||
|
||||
This construct ensures that [application]*bash* will
|
|
@ -2,7 +2,7 @@
|
|||
:experimental:
|
||||
|
||||
[[chap-Defensive_Coding-Vala]]
|
||||
=== The Vala Programming Language
|
||||
= The Vala Programming Language
|
||||
|
||||
Vala is a programming language mainly targeted at GNOME developers.
|
||||
|
||||
|
@ -33,4 +33,4 @@ reference counting) for `GObject` values. For
|
|||
plain C pointers (such as strings), the programmer has to ensure
|
||||
that storage is deallocated once it is no longer needed (to
|
||||
avoid memory leaks), and that storage is not being deallocated
|
||||
while it is still being used (see <<sect-Defensive_Coding-C-Use-After-Free>>).
|
||||
while it is still being used (see <<sect-Defensive_Coding-C-Use-After-Free>>).
|
17
en-US/snippets/C-Arithmetic-add.adoc
Normal file
17
en-US/snippets/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
en-US/snippets/C-Arithmetic-add_unsigned.adoc
Normal file
13
en-US/snippets/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
en-US/snippets/C-Arithmetic-mult.adoc
Normal file
10
en-US/snippets/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
en-US/snippets/C-Globals-String_Array.adoc
Normal file
8
en-US/snippets/C-Globals-String_Array.adoc
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
static const char *const string_list[] = {
|
||||
"first",
|
||||
"second",
|
||||
"third",
|
||||
NULL
|
||||
};
|
||||
|
45
en-US/snippets/C-Pointers-remaining.adoc
Normal file
45
en-US/snippets/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
en-US/snippets/C-String-Functions-format.adoc
Normal file
14
en-US/snippets/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);
|
||||
}
|
||||
|
10
en-US/snippets/C-String-Functions-snprintf-incremental.adoc
Normal file
10
en-US/snippets/C-String-Functions-snprintf-incremental.adoc
Normal 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);
|
||||
}
|
||||
|
4
en-US/snippets/C-String-Functions-snprintf.adoc
Normal file
4
en-US/snippets/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);
|
||||
|
5
en-US/snippets/C-String-Functions-strncat-emulation.adoc
Normal file
5
en-US/snippets/C-String-Functions-strncat-emulation.adoc
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
char buf[10];
|
||||
snprintf(buf, sizeof(buf), "%s", prefix);
|
||||
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%s", data);
|
||||
|
3
en-US/snippets/C-String-Functions-strncat-merged.adoc
Normal file
3
en-US/snippets/C-String-Functions-strncat-merged.adoc
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
snprintf(buf, sizeof(buf), "%s%s", prefix, data);
|
||||
|
5
en-US/snippets/C-String-Functions-strncpy.adoc
Normal file
5
en-US/snippets/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
en-US/snippets/Features-HSM-GNUTLS-PIN.adoc
Normal file
18
en-US/snippets/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
en-US/snippets/Features-HSM-GNUTLS.adoc
Normal file
40
en-US/snippets/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
en-US/snippets/Features-HSM-NSS-PIN.adoc
Normal file
23
en-US/snippets/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
en-US/snippets/Features-HSM-NSS.adoc
Normal file
56
en-US/snippets/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
en-US/snippets/Features-HSM-OpenSSL.adoc
Normal file
64
en-US/snippets/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);
|
||||
|
46
en-US/snippets/Features-TLS-Client-GNUTLS-Connect.adoc
Normal file
46
en-US/snippets/Features-TLS-Client-GNUTLS-Connect.adoc
Normal 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);
|
||||
}
|
||||
|
21
en-US/snippets/Features-TLS-Client-GNUTLS-Credentials.adoc
Normal file
21
en-US/snippets/Features-TLS-Client-GNUTLS-Credentials.adoc
Normal 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);
|
||||
}
|
||||
|
38
en-US/snippets/Features-TLS-Client-GNUTLS-Verify.adoc
Normal file
38
en-US/snippets/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
en-US/snippets/Features-TLS-Client-NSS-Close.adoc
Normal file
11
en-US/snippets/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
en-US/snippets/Features-TLS-Client-NSS-Connect.adoc
Normal file
76
en-US/snippets/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);
|
||||
}
|
||||
|
22
en-US/snippets/Features-TLS-Client-OpenJDK-Connect.adoc
Normal file
22
en-US/snippets/Features-TLS-Client-OpenJDK-Connect.adoc
Normal 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);
|
||||
|
22
en-US/snippets/Features-TLS-Client-OpenJDK-Context.adoc
Normal file
22
en-US/snippets/Features-TLS-Client-OpenJDK-Context.adoc
Normal 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);
|
||||
|
|
@ -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);
|
||||
|
3
en-US/snippets/Features-TLS-Client-OpenJDK-Hostname.adoc
Normal file
3
en-US/snippets/Features-TLS-Client-OpenJDK-Hostname.adoc
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
params.setEndpointIdentificationAlgorithm("HTTPS");
|
||||
|
14
en-US/snippets/Features-TLS-Client-OpenJDK-Import.adoc
Normal file
14
en-US/snippets/Features-TLS-Client-OpenJDK-Import.adoc
Normal 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;
|
||||
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
7
en-US/snippets/Features-TLS-Client-OpenJDK-Use.adoc
Normal file
7
en-US/snippets/Features-TLS-Client-OpenJDK-Use.adoc
Normal 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);
|
||||
|
67
en-US/snippets/Features-TLS-Client-OpenSSL-CTX.adoc
Normal file
67
en-US/snippets/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);
|
||||
}
|
||||
|
51
en-US/snippets/Features-TLS-Client-OpenSSL-Connect.adoc
Normal file
51
en-US/snippets/Features-TLS-Client-OpenSSL-Connect.adoc
Normal 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);
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
9
en-US/snippets/Features-TLS-Client-OpenSSL-Init.adoc
Normal file
9
en-US/snippets/Features-TLS-Client-OpenSSL-Init.adoc
Normal 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();
|
||||
|
10
en-US/snippets/Features-TLS-Client-Python-Connect.adoc
Normal file
10
en-US/snippets/Features-TLS-Client-Python-Connect.adoc
Normal 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")
|
||||
|
|
@ -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
en-US/snippets/Features-TLS-GNUTLS-Disconnect.adoc
Normal file
10
en-US/snippets/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
en-US/snippets/Features-TLS-GNUTLS-Init.adoc
Normal file
5
en-US/snippets/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
en-US/snippets/Features-TLS-GNUTLS-Use.adoc
Normal file
14
en-US/snippets/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
en-US/snippets/Features-TLS-NSS-Close.adoc
Normal file
4
en-US/snippets/Features-TLS-NSS-Close.adoc
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
SECMOD_DestroyModule(module);
|
||||
NSS_ShutdownContext(ctx);
|
||||
|
16
en-US/snippets/Features-TLS-NSS-Includes.adoc
Normal file
16
en-US/snippets/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
en-US/snippets/Features-TLS-NSS-Init.adoc
Normal file
67
en-US/snippets/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
en-US/snippets/Features-TLS-NSS-Use.adoc
Normal file
18
en-US/snippets/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
en-US/snippets/Features-TLS-Nagle.adoc
Normal file
8
en-US/snippets/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
en-US/snippets/Features-TLS-OpenJDK-Parameters.adoc
Normal file
23
en-US/snippets/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()]));
|
||||
|
26
en-US/snippets/Features-TLS-OpenSSL-Connection-Close.adoc
Normal file
26
en-US/snippets/Features-TLS-OpenSSL-Connection-Close.adoc
Normal 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);
|
||||
|
3
en-US/snippets/Features-TLS-OpenSSL-Context-Close.adoc
Normal file
3
en-US/snippets/Features-TLS-OpenSSL-Context-Close.adoc
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
SSL_CTX_free(ctx);
|
||||
|
27
en-US/snippets/Features-TLS-OpenSSL-Errors.adoc
Normal file
27
en-US/snippets/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
en-US/snippets/Features-TLS-Python-Close.adoc
Normal file
3
en-US/snippets/Features-TLS-Python-Close.adoc
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
sock.close()
|
||||
|
4
en-US/snippets/Features-TLS-Python-Use.adoc
Normal file
4
en-US/snippets/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
en-US/snippets/Go-Error_Handling-IO.adoc
Normal file
21
en-US/snippets/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
en-US/snippets/Go-Error_Handling-Regular.adoc
Normal file
19
en-US/snippets/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
en-US/snippets/Java-Finally.adoc
Normal file
8
en-US/snippets/Java-Finally.adoc
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
InputStream in = new BufferedInputStream(new FileInputStream(path));
|
||||
try {
|
||||
readFile(in);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
|
32
en-US/snippets/Java-JNI-Pointers.adoc
Normal file
32
en-US/snippets/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
en-US/snippets/Java-Language-ReadArray.adoc
Normal file
35
en-US/snippets/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
en-US/snippets/Java-SecurityManager-Callback.adoc
Normal file
36
en-US/snippets/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
en-US/snippets/Java-SecurityManager-Privileged.adoc
Normal file
15
en-US/snippets/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
en-US/snippets/Java-SecurityManager-Unprivileged.adoc
Normal file
24
en-US/snippets/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
en-US/snippets/Java-TryWithResource.adoc
Normal file
5
en-US/snippets/Java-TryWithResource.adoc
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
try (InputStream in = new BufferedInputStream(new FileInputStream(path))) {
|
||||
readFile(in);
|
||||
}
|
||||
|
8
en-US/snippets/Shell-Input_Validation.adoc
Normal file
8
en-US/snippets/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
|
||||
|
13
en-US/snippets/Tasks-Serialization-XML-Expat-Create.adoc
Normal file
13
en-US/snippets/Tasks-Serialization-XML-Expat-Create.adoc
Normal 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);
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
18
en-US/snippets/Tasks-Serialization-XML-OpenJDK-Errors.adoc
Normal file
18
en-US/snippets/Tasks-Serialization-XML-OpenJDK-Errors.adoc
Normal 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();
|
||||
}
|
||||
}
|
||||
|
23
en-US/snippets/Tasks-Serialization-XML-OpenJDK-Imports.adoc
Normal file
23
en-US/snippets/Tasks-Serialization-XML-OpenJDK-Imports.adoc
Normal 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;
|
||||
|
|
@ -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.
|
||||
}
|
||||
|
12
en-US/snippets/Tasks-Serialization-XML-Qt-QDomDocument.adoc
Normal file
12
en-US/snippets/Tasks-Serialization-XML-Qt-QDomDocument.adoc
Normal 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);
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue