locale: <s:property value='locale.toString()'/>
<s:if test='locale.toString() == "en"'>
. . .
</s:if>
Output is "en", or "ru_RU", or like this.
<s:if test='locale.toString() == "en"'>
. . .
</s:if>
Output is "en", or "ru_RU", or like this.
|
/
|
Start searching from the root directory (i.e / directory) | |
|
-name
|
Given search text is the filename rather than any other attribute of a file | |
|
'program.c'
|
Search text that we have entered. Always enclose the filename in single quotes.. why to do this is complex.. so simply do so. |
1
2
3
| -----BEGIN CERTIFICATE-----(base 64 encoded stuff)-----END CERTIFICATE----- |
1
2
3
| -----BEGIN PRIVATE KEY-----(base 64 encoded stuff)-----END PRIVATE KEY----- |
cat cert.pem key.pem > cert-with-key.pem.
While you could arbitrarily combine as many PEM blocks as you wanted
into one file, typically they are kept separate except for this one
case. You can get a human-readable description of a cert in PEM format
with openssl x509 -in cert.pem -noout -text. (Certs are X509 formatted, hence the ‘x509′ subcommand to openssl.) For keys, the command is openssl rsa -in key.pem -text -noout.
Private keys can also be encrypted, in which case the marker block will
say BEGIN ENCRYPTED PRIVATE KEY. You can create the decrypted form of
the key with openssl rsa -in key-encrypted.pem -out key-decrypted.pem. openssl pkcs12 -in file.p12. Add -info
for a little bit more metadata. Note that if the file includes a
private key, openssl will ask you for another password after asking for
the decryption password for the PKCS12 file. This second password is
used to encrypt the private key before displaying its PEM data to you.
You could put this data in a separate file and decrypt it as shown above
if you want the decrypted form.openssl pkcs12 -export -out cert-and-key.p12 -in cert.pem -inkey key.pemopenssl pkcs12 -export -out cert-and-key-with-ca.p12 -in cert.pem -inkey key.pem -CAfile /path/to/cacert.pem -chainopenssl pkcs12 -export -out cacert.p12 -in cacert.pem -nokeyskeytool -importkeystore -destkeystore cert-and-key-with-ca.jks -srckeystore cert-and-key-with-ca.p12 -srcstoretype PKCS12keytool -keystore cacert-added-then-cert-nokey.jks -import -file cacert.pem -alias cacert (Say yes when it asks if you want to trust the CA) keytool -keystore cacert-added-then-cert-nokey.jks -import -file cert.pem -alias certkeytool -keystore cacert-added-then-cert-withkey.jks -import -file cacert.pem -alias cacert (Say yes when it asks if you want to trust the CA) keytool -destkeystore cacert-added-then-cert-withkey.jks -importkeystore -srckeystore cert-and-key.p12 -srcstoretype PKCS12javax.net.debug
to “all” for maximum verbosity. You can download the OpenJDK code and
step through it by looking for where the debug statements are printed.
It’s not as good as a debugger, but there’s not much code and the debug
statements are frequent enough that it’s not hard to follow. Wireshark is also extremely useful.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| /* * The static getDefault() methods return the non-SSL * factory classes, so they have to be cast. */SSLServerSocketFactory serverSocketFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();SSLServerSocket serverSocket = (SSLServerSocket) serverSocketFactory.createServerSocket(8443);SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();SSLSocket socket = (SSLSocket) socketFactory.createSocket("localhost", 8443);// do the standard socket stuff with byte streams, etc. |
java.security.KeyStore is used in the process of creating both keystores and truststores. I will be careful to capitalize as KeyStore
when I mean the class as opposed to the conceptual items. For the
server socket, we need to specify a keystore containing server-cert and
server-key. We also need a truststore containing client-ca-cert. For the
client socket, we need a keystore containing the client cert and key
and a truststore containing the server-ca-cert. To get these keystores
and truststores, we need to construct KeyStore instances with the appropriate certificate and key data. KeyStores can be created for JKS or PKCS12 files. This code creates a KeyStore and loads data from an input stream. After load() has been called, the KeyStore is ready for use.
1
2
3
4
5
6
7
8
9
10
| // keyStoreType is either "JKS" or "PKCS12"KeyStore keyStore = KeyStore.getInstance(keyStoreType);keyStore.load(inputStream, keyStorePassword.toCharArray());A
KeyStore is just an intermediate step, though. Once we have a KeyStore
with the keystore data and a KeyStore with the truststore data, the next
step is a TrustManager (for a truststore) and a KeyManager (for a keystore).TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX", "SunJSSE");trustManagerFactory.init(trustStore); |
TrustManagerFactory instance. JSSE is
fairly agnostic towards cryptosystems, so it can, at least in theory,
support things beyond X509. In practice, X509 is all we care about, and
looking in the OpenJDK source code will give the impression that X509 is
all it’s built to support anyway. The “PKIX” algorithm implements
cert-chain validation for X509 certs. A TrustManagerFactory can create a TrustManager[], one for each type of “trust material”. We only care about the X509TrustManager instance.
1
2
3
4
5
6
7
8
9
10
11
| X509TrustManager x509TrustManager = null;for (TrustManager trustManager : trustManagerFactory.getTrustManagers()) { if (trustManager instanceof X509TrustManager) { x509TrustManager = (X509TrustManager) trustManager; break; }}if (x509TrustManager == null) { throw new NullPointerException();} |
X509TrustManager instance we want. A similar approach will get you the X509KeyManager.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509", "SunJSSE");keyManagerFactory.init(keyStore, password.toCharArray());X509KeyManager x509KeyManager = null;for (KeyManager keyManager : keyManagerFactory.getKeyManagers()) { if (keyManager instanceof X509KeyManager) { x509KeyManager = (X509KeyManager) keyManager; break; }}if (x509KeyManager == null) { throw new NullPointerException();} |
SSLContext. Here’s the code to create a SSLServerSocket.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| // load in the appropriate keystore and truststore for the server// get the X509KeyManager and X509TrustManager instancesSSLContext sslContext = SSLContext.getInstance("TLS");// the final null means use the default secure random sourcesslContext.init(new KeyManager[]{keyManager}, new TrustManager[]{trustManager}, null);SSLServerSocketFactory serverSocketFactory = sslContext.getServerSocketFactory();SSLServerSocket serverSocket = (SSLServerSocket) serverSocketFactory.createServerSocket(PORT);serverSocket.setNeedClientAuth(true);// prevent older protocols from being used, especially SSL2 which is insecureserverSocket.setEnabledProtocols(new String[]{"TLSv1"});// you can now call accept() on the server socket, etc |
SSLSocket. Make sure you
don’t use the same keystore and truststore that you did for the server!
They almost certainly need to be different.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| // load in the appropriate keystore and truststore for the client// get the X509KeyManager and X509TrustManager instancesSSLContext sslContext = SSLContext.getInstance("TLS");sslContext.init(new KeyManager[]{keyManager}, new TrustManager[]{trustManager}, null);SSLSocketFactory socketFactory = sslContext.getSocketFactory();SSLSocket socket = (SSLSocket) socketFactory.createSocket("localhost", SslServer.PORT);socket.setEnabledProtocols(new String[]{"TLSv1"});// read from the socket, etc |
KeyStore implementation has some bugs, so depending on how you set up your server-side trust store, it may or may not work.sun.security.ssl.X509TrustManagerImpl and sun.security.validator.KeyStores shows that the logic used to get issuers is simply wrong. In the case where the KeyStore entry in a KeyStore
is a key entry (not a bare cert), it unconditionally uses the first
cert in the chain of certs for that key, regardless of whether or not it
is even a CA cert or the actual issuing cert in the chain. In fact, the
documentation for KeyStore.getCertificateChain() says that the root cert is the last
cert in the chain, not the first. This code was probably tested using
self-signed certs (which only have one cert in the chain, so it will
always work) and not using separate CA certs.X509TrustManager KeyStore. This is the PKCS12 loading bug. When you connect a client, you get java.net.SocketException: Broken pipe on the client side and javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found on the server. This happens because the server has sent a CertificateRequest in the ServerHello, but has not included any DNs for the client to look up certs by.X509TrustManager.getIssuers()
mistakenly returns client-cert as an issuer (which it is not) and does
not return client-ca-cert. The correct behavior would be to return only
client-ca-cert. (An “issuer” is a CA.) In this case, you get javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate on the client and javax.net.ssl.SSLHandshakeException: null cert chain on the server. The server sends the DN of client-cert in the CertificateRequest part of the ServerHello.
The client (correctly) does not find any certs signed by that cert, so
it returns no certificates. The server rejects the connection with error
code 42 for “bad certificate” (see the TLS RFC section A.3 for error
codes) and dies with its own error that (accurately) says there is a
null certificate chain from the client.KeyStore is not suffering from the same bug as the PKCS12 code. A KeyStore loaded from a JKS containing only
client-ca-cert does end up with a cert in it. Since it’s just a cert,
not a cert in a chain attached to a key, it avoids the buggy code path
in KeyStores, so the correct DN gets sent to the client in the ServerHello and all proceeds normally.| Key contents | Key type | Result of getIssuers() |
|---|---|---|
| client-cert, client-key, client-ca-cert | PKCS12 | client-cert |
| client-cert, client-key, client-ca-cert | JKS | client-cert |
| client-cert, client-key | PKCS12 | client-cert |
| client-cert, client-key | JKS | client-cert |
| client-cert, client-ca-cert | PKCS12 | (empty) |
| client-ca-cert | PKCS12 | (empty) |
| client-ca-cert added first, then client-cert & client-key | JKS | client-cert and client-ca-cert |
| client-ca-cert added first, then client-cert | JKS | client-cert and client-ca-cert |
| client-ca-cert | JKS | client-ca-cert (what you want) |
SELECT default_character_set_name FROM information_schema.SCHEMATA
WHERE schema_name = "schemaname";
SELECT CCSA.character_set_name FROM information_schema.`TABLES` T,
information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA
WHERE CCSA.collation_name = T.table_collation
AND T.table_schema = "schemaname"
AND T.table_name = "tablename";
SELECT character_set_name FROM information_schema.`COLUMNS` WHERE table_schema = "schemaname"
AND table_name = "tablename"
AND column_name = "columnname";
ALTER TABLE `SCHEMANAME`.`TABLE1` ADD CONSTRAINT `FK_TABLE2_COLUMN` FOREIGN KEY (`FK_COLUMN`)
REFERENCES `SCHEMANAME`.`TABLE2`(`PK_COLUMN`);
Adding a column with constraintALTER TABLE `SCHEMANAME`.`TABLE1`
ADD COLUMN `FK_COLUMN` BIGINT(20) NOT NULL,
ADD CONSTRAINT `FK_TABLE2_COLUMN` FOREIGN KEY (`FK_COLUMN`)
REFERENCES `SCHEMANAME`.`TABLE2`(`PK_COLUMN`);