This is a brief rundown of especially the commands described in the Java Security Trail. For full understanding, read the trail.

Policy files

Security policies are stored in "policy files". These need to be included either by adding to the <!> $JAVA_HOME/lib/security/java.security file or by using the -Djava.security.policy=<policyfile> option when starting Java. For the former, add a line policy.url.n=<policyfile> where n is a consecutive integer keeping multiple policy.url entries distinct.

The policy files can be edited using the <!> policytool program that comes with Java. The trail describes how the 1.5 tool works, the 1.6 tool has less keystore-related functionality.

Permissions to do "stuff" can be granted either to code from a particular "CodeBase" (URL of the files) or to code signed by a certificate. For a CodeBase, permission can be granted to a URL and all subdirectories thereof by adding '-' to the URL, e.g. http://netarkivet.dk/- to specify permissions for anything from netarkivet.dk.

Permissions are organized by class, e.g. FilePermission controls read/write/execute permissions for files. All permissions have a target, e.g. a file or directory for FilePermission. The syntax of the target is defined by the permission class. For FilePermission, it is simply a file. Again, permission for all subdirectories can be given by adding a '-' after the file. Note also that properties can be used in the target, such as ${user.home}.

The Trail mentions that on Unix there may be some DNS-related hacks required. I didn't find this necessary on an Ubuntu 7.10 box.

Java applets by default have a security manager installed, but Java applications do not. To use a security manager, run Java with <!> -Djava.security.manager option.

Default policy is to let anyone listen to any port > 1024 and to allow reading some specific properties like java.vendor.name, os.name etc.

The policy tool is fairly simple to use. For example, to create a file read policy for code from a given URL, run policytool, click Add policy entry, enter the URL at CodeBase, click Add permission, select !FilePermission, enter the relevant file at Target, select read under actions, click Ok, click Done, pick Save menu item and save the policy under whatever name you like. The file saved there is the one that needs to be specified in the java.security file or on the command line with -Djava.security.policy.

Certificates

We will be using certificates at least to allow our code to 1) write new files to the bitarchive, and 2) perform the correction action. Other people's code may not be given the rights to even create files, they may only get to write to a given OutputStream. We won't need an infrastructure to accept arbitrary certificates, just to accept our own, which can be done during deployment.

Signing happens at the jar file level using the jarsigner tool. It requires a key, of course, which can be made with keytool -genkey. I'll leave certificate authorities out of this.

Creating a key can be done with <!> keytool -genkey -alias signFiles -keystore ourstore. The alias is arbitrary and here indicates what the key is meant to be used for. The keystore is the file that the key is stored in. Both the key and the keystore will be password protected. keytool will ask for these passwords. It will also ask for some identifying information such as name, organization etc.

The keystore generated (named with the -keystore option) is valid for 90 days unless the -validity option is used.

A jar file can be signed by using <!> jarsigner -keystore ourstore -signedjar SignedFile.jar File.jar signFiles where SignedFile.jar is the output file, File.jar is the input jar file, and ourstore is the keystore generated earlier. This, unsurprisingly, creates the SignedFile.jar file, but it will first ask for the keystore password and the key password. This signed jar file can now be sent/installed somewhere just like a normal jar file.

To make use of the signing, the public key needs to be installed in the target system. The command <!> keytool -export -keystore ourstore -alias signFiles -file OurCert.cer extracts the public signFiles key from ourstore into the OurCert.cer file, prompting for the keystore password.

In order to use this public key, the receiver (target system, in our case) will need to import it into a keystore using <!> keytool -import -alias sender -file OurCert.cer -keystore systemstore. If systemstore doesn't exist yet, keytool will ask for a keystore password for it. The alias sender has no connection with the alias used during creation of the key. This will also print out some fingerprinting information. The fingerprints can be read from the certificate file using keytool -printcert -file OurCert.cer.

To use this keystore in policies, use the policytool and choose the Change keystore menu item. Then input the location of the systemstore keystore as a URL and press OK. You can now, when making new policy entries, use the alias specified when importing the key (sender, in our case) in the Signed by field, optionally in combination with a CodeBase. The remaining part of creating and adding a policy works just like when using only a CodeBase entry above.

Notes for our implementation

We need to either run all of bitarchive under one security manager, or else apply a security manager to anything that comes from the outside. The former method requires that a number of things that our code does, like logging, connection to JMS, registering JMX beans etc, will have to be explicitly allowed in the security profile. The latter approach requires more code changes and doesn't prevent errors in the bitarchive from damaging the archive. Unfortunately, the security policies are not fine-grained enough that they can define e.g. that only the RemoveAndGetOneFile method can move files away from the filedir directory, so the actual protection given by running a security policy on everything is somewhat limited. It's not possible to allow creation/moving/rewriting separately, those are all considered writes.

JavaSecurityCommands (last edited 2010-08-16 10:24:38 by localhost)