Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Java security evolution and concepts, Part 3: Applet security

Tackle Java applet security with confidence

  • Print
  • Feedback

Page 6 of 6

C:\signtool> type rags.cer
-----BEGIN CERTIFICATE-----
MIIDSDCCArGgAwIBAgIDB8CTMA0GCSqGSIb3DQEBBAUAMIHEMQswCQYDVQQGEwJaQTEVMBMGA1UE
CBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xHTAbBgNVBAoTFFRoYXd0ZSBDb25z
dWx0aW5nIGNjMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMRkwFwYD
VQQDExBUaGF3dGUgU2VydmVyIENBMSYwJAYJKoZIhvcNAQkBFhdzZXJ2ZXItY2VydHNAdGhhd3Rl
LmNvbTAeFw0wMDEyMTMyMTE4MzhaFw0wMTEyMjEyMjIwMjJaMIGPMQswCQYDVQQGEwJVUzELMAkG
A1UECBMCTUExEzARBgNVBAcTCkJ1cmxpbmd0b24xHTAbBgNVBAoTFFJhZ2hhdmFuIE4uIFNyaW5p
dmFzMSAwHgYDVQQLExdTdW4gTWljcm9zeXN0ZW1zIChNRERSKTEdMBsGA1UEAxMUUmFnaGF2YW4g
Ti4gU3Jpbml2YXMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMIZayo84gLZ+Lfe/rR5Tx5p
qIBuywwMVwc7lh2iwFc80JJJH8HrZspeQ1X8ixkT0az1rFQtVcM7KmuPGU6Xn4bl/ZLNG45L5KD2
PjNn565YJUP1gIjRtIWhZucuVvQU2b08dvgsLFBL6QhlxIcInTeqtz4C0RHPHviwroPhrMapAgMB
AAGjezB5MB8GA1UdJQQYMBYGCCsGAQUFBwMDBgorBgEEAYI3AgEWMBEGCWCGSAGG+EIBAQQEAwIE
EDAdBgNVHQQEFjAUMA4wDAYKKwYBBAGCNwIBFgMCB4AwFgYDVR0RBA8wDYILd3d3LnN1bi5jb20w
DAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQQFAAOBgQAyKVQucm4GlINqao2LD0OBQe5Vc47/NguS
/KL6jigW0ojkBJW31FmArtiMT9TpHx6E0qhLZrHcFPqcwdU1Ujr1WUox14tk3UHofOax2BQFHol/
uEw5HVbD+3qtSxMomGPkiDKewhkApKBrdMjWW7Z6dt8o7th3BOfZtynEbQf85A==
-----END CERTIFICATE-----


The public key created above can be imported into a keystore to enable trusting code that is signed by the private key corresponding to the public key.

C:\signtool> keytool -v -printcert -file rags.cer
Owner: CN=Raghavan N. Srinivas, OU=Sun Microsystems (MDDR), O=Raghavan N. Srinivas, L=Burlington, ST=MA, C=US
Issuer: EmailAddress=server-certs@thawte.com, CN=Thawte Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
Serial number: 7c093
Valid from: Wed Dec 13 16:18:38 EST 2000 until: Fri Dec 21 17:20:22 EST 2001
Certificate fingerprints:
         MD5:  34:6C:32:F9:2E:0D:0D:B3:99:13:FC:EC:F3:D9:8B:AF
         SHA1: 77:5D:D9:EC:62:4D:C7:47:D9:58:05:73:B9:34:60:F6:38:A8:36:94


The following command lists the keys in the keystore, which indicates that it's the default type -- Java Key Store (jks). Other formats, such pkcs12, can be used as well; however, they require that JSSE be installed.

C:\signtool> keytool -list -keystore writeFile.keystore
Enter keystore password:  
Keystore type: jks
Keystore provider: SUN
Your keystore contains 1 entry:
rags, Thu Dec 14 12:39:31 EST 2000, trustedCertEntry,
Certificate fingerprint (MD5): 34:6C:32:F9:2E:0D:0D:B3:99:13:FC:EC:F3:D9:8B:AF


jarsigner

The jarsigner tool accesses a keystore created and managed by keytool, when it needs to find the private key and its associated certificate chain to use for signing a jar file. Since passwords protect access to the keystore and to private keys, only people who know the passwords will be able to access the key and use it to sign a jar file. The jarsigner tool prompts for needed passwords.

Some useful options for jarsigner are listed in Table 2.

Table 2. Selected jarsigner options
Option Description
-storepass  Specifies the required password to access the keystore during signing 
-keypass  Specifies the password used to protect the private key of the keystore alias entry 
-signedjar  Specifies the name to be used for the signed jar file 
-verify  Jar file verification 
-verbose  Output extra information as to the progress of the jar signing or verification 
-certs  Used in conjunction with -verify and -verbose options, the output includes certificate information for each signer of the jar file 


Note: in this article's code examples, I did not use jarsigner to sign the files; instead, I used Netscape's signtool.

policytool

The policytool command creates and modifies the external policy configuration files that define the installation's security policy. This tool has a graphical user interface, with which you select buttons and other options rather than type in commands as you would with the other tools. The tool modifies a regular text policy file. For default policy implementation and policy file syntax, see Resources.

Figure 4 below shows the top-level window used to specify the location of the policy file and the keystore. If the policy file does not exist, an empty file may need to be created before using this tool. The window also displays the different entries.

Figure 4. policytool: modify the locations
of the keystore and the policy file
Click on thumbnail to view
full-size image (14 KB)



Figure 5 below shows the next step of adding or modifying a policy entry. You may set the CodeBase and the SignedBy properties in this window.

Figure 5. policytool: CodeBase and SignedBy properties
Click on thumbnail to view
full-size image (15 KB)



Finally, Figure 6 illustrates how permissions can be added or modified.

Figure 6. policytool: setting permissions



The file {java.home}/lib/security/java.security by default contains two policy files -- {java.home}/lib/security/java.policy and {user.home}/.java.policy. policytool typically modifies the latter file.

Later, we will see several examples of how to modify policy files; this can be accomplished either with the policytool or a text editor. policytool does the validation (enforces the syntax, checks for keys in the keystore, and so on), a considerable advantage.

Netscape's signtool for object signing

Like jarsigner, Netscape's signtool is a stand-alone command-line tool that creates digital signatures and uses the Java Archive (JAR) format to associate them with files in a directory. Some useful options for signtool are listed in Table 3.

Table 3. Selected signtool options
Option Description
-d certdir  Specifies your certificate database directory containing key3.db and cert7.db files  
-G nickname  Generates a new private-public key pair and corresponding object-signing certificate with the given nickname 
-k key  Specifies the nickname (key) of the certificate you want to sign with 
-l  Lists signing certificates, including issuing CAs; specifies invalid or expired certificates 
-L  Lists the certificates in your database. An asterisk appears to the left of the nickname for any certificate that can be used to sign objects with signtool 
-v archive  Verifies the cryptographic integrity of the archive 
-w archive  Displays the names of signers of any files in the archive 
-Z jarfile  Creates a jar file with the specified name 


Several examples of signtool commands are illustrated later.

Applet Deployment under Java 2 version 1.2

Instructions for running a Java 2, version 1.2 applet, including source code, is available from http://java.sun.com/security/signExample12/.

Without repeating Sun's instructions here, let's summarize what happened when we followed them:

  • We discovered that applets can be deployed for plug-in support by using the Java plug-in HTML converter (see Resources).
  • By default, the applet generated a security exception due to the restrictions placed on downloaded code.
  • We imported the public key corresponding to the key used to sign the code.
  • To overcome the restrictions placed, we provided permissions based on the URL and the signer.
  • Finally, we were able to run the code without generating an exception. In fact, the code runs identically on Netscape Navigator and Internet Explorer without any changes.


Be aware that to run applet code that is signed, we had to import the public key of the signer into the keystore before we could run the code. This may not always be feasible. Worse yet, the process of importing signatures to a number of client machines does not scale well. Both these issues have been fixed in version 1.3 of the Java plug-in.

Evolution to Java 2 version 1.3

To utilize a variety of security enhancements in the platform and the Java plug-in, we will try to upgrade the applet that we studied in the 1.2 environment to the 1.3 environment using the plug-in. Some of the enhancements in the platform include:

  • Full support for RSA signatures.
  • Full interoperation with Verisign's code-signing certificates. As such, keytool is now able to import Verisign certificates.


Some of the enhancements to the Java plug-in v1.3 include:

  • New support for RSA-signed applets, thus removing the need to distribute an identitydb.obj file to client machines.
  • Support for the standard Java 2 SDK, Standard Edition version 1.3 security model.


In the earlier example, we simply used signed code. However, it's more interesting to sign and deploy our own applet. With the armory of tools and the knowledge we have now obtained, we are more or less ready for the undertaking.

It's recommended that you delete earlier versions of the plug-in before installing a more recent version. However, I have not seen any major ill effects myself of not doing so. To be reasonably sure that you are running the right version of the plug-in, you may want to use the plug-in panel available via the Control Panel (in Windows).

Generate an RSA-signed applet



The first step in the process will be to sign the code; for this task, I used Netscape's signtool. To sign the code, we need an object- or code-signing certificate, specifically for Netscape. This procedure can vary depending on what Certifying Authority (CA) you use. An important distinction between 1.3 and 1.2: self-certified signatures that worked in 1.2 do not work in 1.3. Signatures must be certified by a standard CA in 1.3. The turnaround times are different, as they involve some form of physical checks. Also, there are different certificate classes. Finally, the process involves some form of payment -- typically in the hundreds of dollars. Typically, this process starts off by generating a key pair. The private key will be stored safely on a local disk or a smart card. The public key is then sent to the CA for certification. Most CAs will follow a manual procedure at this point to ascertain the identity of the signer before issuing a certificate. (For a list of CAs, see Resources.)

Eventually, you will receive a public key encapsulated as a certificate. The public key certificate needs to be imported into Netscape's database. This process can be done in a variety of ways depending on the format used to receive the certificate. You may use the Import A Certificate option in Certificates/Yours in the security window as seen in Figure 7 below. Or you may paste the certificate into a text file and then import it.

Figure 7. Netscape security window: manipulation of certificates
Click on thumbnail to view full-size image (37 KB)



After installing the certificate, copy the relevant Netscape .db files to the signtool directory:

C:\signtool> copy c:"\Program Files\netscape\users\rags"\*.db
c:\Program Files\netscape\users\rags\cert7.db
c:\Program Files\netscape\users\rags\key3.db
c:\Program Files\netscape\users\rags\secmod.db


The files contain the keys and certificates needed to sign the code. The -l and -L options on signtool can be used to find certificates that can be used for code signing:

C:\signtool> signtool -l
using certificate directory: .
Object signing certificates
---------------------------------------
Sun Microsystems Inc.'s Thawte Consulting cc ID
    Issued by: Thawte Server CA (Thawte Server CA)
    Expires: Fri Dec 21, 2001
Raghavan N. Srinivas's Thawte Consulting cc ID
    Issued by: Thawte Server CA (Thawte Server CA)
    Expires: Fri Dec 21, 2001
Raghavan N. Srinivas's Sun Microsystems Inc ID
    Issued by: SMI Information Technology Test CA - Sun Microsystems Inc (SMI Information Technology Test CA)
    Expires: Fri Nov 24, 2000
---------------------------------------
For a list including CA's, use "signtool -L"
C:\signtool> signtool -L
using certificate directory: .
S Certificates
- ------------
  Verisign Class 1 Public Primary Certification Authority
  GlobalSign Primary Class 3 CA
  ValiCert OCSP Responder
  Verisign/RSA Commercial CA
  TC TrustCenter, Germany, Class 2 CA
  GlobalSign Primary Class 2 CA
  E-Certify Commerce ID
  Entrust.net Secure Personal CA
  TC TrustCenter, Germany, Class 3 CA
  Digital Signature Trust Co. Global CA 1
  Thawte Personal Freemail CA
  ValiCert Class 1 VA
  TC TrustCenter, Germany, Class 4 CA
  ValiCert Class 2 VA
  Verisign Class 3 Public Primary Certification Authority - G3
  Verisign/RSA Secure Server CA
  Thawte Personal Basic CA
  ValiCert Class 3 VA
  Verisign Class 4 Public Primary Certification Authority - G3
* Sun Microsystems Inc.'s Thawte Consulting cc ID
  GlobalSign Partners CA
  Equifax Secure CA
  Deutsche Telekom AG Root CA
  Sun Microsystems Inc TEST Root CA - GTE Corporation
  Digital Signature Trust Co. Global CA 2
  GTE CyberTrust Global Root
  GTE CyberTrust Root 3
  GTE CyberTrust Japan Secure Server CA
  VeriSign Class 4 Primary CA
  GTE CyberTrust Root 5
  GTE CyberTrust Japan Root CA
  TC TrustCenter, Germany, Class 0 CA
  Verisign Class 2 Public Primary Certification Authority - G2
  Verisign Class 3 Public Primary Certification Authority - G2
  GlobalSign Primary Class 1 CA
  Thawte Universal CA Root
  Entrust.net Premium 2048 Secure Server CA
* Raghavan N. Srinivas's Thawte Consulting cc ID
  GTE CyberTrust Root CA
  GTE CyberTrust Root 4
  American Express CA
  BelSign Object Publishing CA
  Verisign Class 1 Public Primary Certification Authority - G3
  Sun Microsystems Inc Test Root CA - GTE Corporation
  Sun Microsystems Inc TEST CA - Sun Microsystems Inc
  GTE CyberTrust Root 2
  TC TrustCenter, Germany, Class 1 CA
  Verisign Class 3 Public Primary Certification Authority
  Verisign Class 4 Public Primary Certification Authority - G2
  GlobalSign Root CA
  Personal Freemail RSA 1999.9.16 - Thawte Consulting
  Thawte Personal Premium CA
  SMI Information Technology Test CA - Sun Microsystems Inc
* Raghavan N. Srinivas's Sun Microsystems Inc ID
  BelSign Secure Server CA
  ABAecom (sub., Am. Bankers Assn.) Root CA
  American Express Global CA
  Equifax Premium CA
  E-Certify Internet ID
  Thawte Server CA
  Digital Signature Trust Co. Global CA 4
  Verisign Class 2 Public Primary Certification Authority - G3
  Verisign Class 2 Public Primary Certification Authority
  Digital Signature Trust Co. Global CA 3
  Verisign Class 1 Public Primary Certification Authority - G2
  Thawte Premium Server CA
  Entrust.net Secure Server CA
- ------------
Certificates that can be used to sign objects have *'s to their left.


Notice the *, which indicates a code-signing certificate. Next, sign the file and generate the jar file:

C:\signtool> mkdir writeFileDir
C:\signtool> copy writeFile.class writeFileDir
C:\signtool> signtool -k "Raghavan N. Srinivas's Thawte Consulting cc ID" -Z writeFile.jar writeFileDir
using certificate directory: .
Generating writeFileDir/META-INF/manifest.mf file..
--> writeFile.class
adding writeFileDir/writeFile.class to writeFile.jar...(deflated 44%)
Generating zigbert.sf file..
Enter Password or Pin for "Communicator Certificate DB":
Enter Password or Pin for "Communicator Certificate DB":
adding writeFileDir/META-INF/manifest.mf to writeFile.jar...(deflated 15%)
adding writeFileDir/META-INF/zigbert.sf to writeFile.jar...(deflated 27%)
adding writeFileDir/META-INF/zigbert.rsa to writeFile.jar...(deflated 36%)
tree "writeFileDir" signed successfully


Finally, verify the jar file:

C:\signtool> signtool -w writeFile.jar
using certificate directory: .
Signer information:
nickname: Raghavan N. Srinivas's Thawte Consulting cc ID
subject name: CN=Raghavan N. Srinivas, OU=Sun Microsystems (MDDR), O=Raghavan N. Srinivas, L=Burlington, ST=MA, C=US
issuer name: E=server-certs@thawte.com, CN=Thawte Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA


This certificate may be imported into the Java .keystore, if needed, using the following steps:

  1. Export the certificate as a pkcs12 format -- default Netscape support
  2. Use the .p12 file as a keystore of storetype pkcs12 -- supported by installing JSSE; alternatively, export out of the pkcs12 keystore and import into the default JKS keystore


The following command lists the keys in the pkcs12 keystore after the certificate was exported from the navigator:

C:\signtool> keytool -list -storetype pkcs12 -keystore rags.p12
Enter keystore password: 
Keystore type: pkcs12
Keystore provider: SunJSSE
Your keystore contains 1 entry:
raghavan n. srinivas's thawte consulting cc id, Thu Dec 14 13:25:44 EST 2000, keyEntry,
Certificate fingerprint (MD5): 
After the jar file has been successfully signed, we are ready to deploy the applet.

Deploy the applet

Having signed the code as highlighted in the previous step, we are now ready to deploy the applet -- almost. The deployment directory must contain the signed jar file and the HTML file for the code to be downloaded and run, as illustrated in the version 1.2 example earlier.

Move writeFile.jar to the deployment directory. The HTML file needs to work with version 1.3 of the Java 2 plug-in. The final writeFile.html in the deployment directory must look something like the code below. Notice that this is only a slight modification of the HTML file we used earlier with changes to incorporate the later version of the plug-in:

<html>
<title> Java Security Example: Writing Files</title>
<h1> Java Security Example: Writing Files </h1>
<hr>
Here's an applet that tries to write to the file <code>/tmp/foo</code>
on a Solaris system (or to the file <code>C:\tmpfoo</code> on a
Windows 95 or Windows NT system.)
<p>
<!--"CONVERTED_APPLET"-->
<!-- CONVERTER VERSION 1.0 -->
<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
WIDTH = 500 HEIGHT = 50  codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0">
<PARAM NAME = CODE VALUE = writeFile.class>
<PARAM NAME = ARCHIVE VALUE = "writeFile.jar">
<PARAM NAME="type" VALUE="application/x-java-applet;version=1.3">
<COMMENT>
<EMBED type="application/x-java-applet;version=1.3" 
java_CODE = writeFile.class java_ARCHIVE = "writeFile.jar" 
WIDTH = 500 HEIGHT = 50   pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html">
<NOEMBED>
</COMMENT>
</NOEMBED></EMBED>
</OBJECT>
<!--
<APPLET  CODE = writeFile.class ARCHIVE = "writeFile.jar" WIDTH = 500 HEIGHT = 50 >
</APPLET>
-->
<!--"END_CONVERTED_APPLET"-->
<p>
and here's the <a href=writeFile.java>source</a>. 
<p>
This applet is a signed applet.
</center>
<hr>
</html>


Having deployed the applet, you are now ready to run it. Applets can be tested by deploying them initially on a local system. Eventually, they will need to be deployed in a Web server environment.

Run the applet

Having deployed the applet on the server, we are now ready to run it from the client. It's not necessary to have a Web server to test the deployment. It can be run from a filesystem using the file: protocol instead of http:.

Before running the applet, make sure that the policy files, ${java.home}/lib/security/java.policy and ${user.home}/.java.policy, do not accord any special permissions besides the default.

Point the browser at writeFile.html in the publicly available URL. If you do not have the latest version of the plug-in installed, you may have to go through the additional step of installing it. When users of the Java plug-in encounter an RSA-signed applet, the plug-in will verify that the applet is correctly signed, and that the RSA certificate chain and the root CA are valid. If these are all valid, the plug-in will pop up a security dialog explaining who signed the applet and providing four options, as shown in Figure 8. Depending on whether you trust the signer of the code, you could do one of the following:

  • Grant this session: If selected, the applet will be granted AllPermission. Any signed applet signed using the same certificate will be trusted automatically within the same browser session.
  • Deny: If selected, the applet will be treated as an untrusted applet.
  • Grant always: If selected, the applet will be granted AllPermission. Any signed applet signed using the same certificate will be trusted automatically in the future, and no security dialog will pop up when this certificate is encountered again. This decision can be changed from the Java plug-in control panel.
  • More Info: If selected, users can examine the attributes of each certificate in the certificate chain in the jar file.


Figure 8. Plug-in warning pop-up window
Click on thumbnail
to view full-size image (16 KB)



Once the user selects the options from the security dialog, the applet will run in the corresponding security context. All of these decisions are determined on the fly, and no preconfiguration is required.

All certificates trusted by the plug-in can be viewed from the plug-in panel, illustrated in Figure 9.

Figure 9. Plug-in trusted certificates
Click on thumbnail
to view full-size image (12 KB)



At this point you may ask, "If trusting the certificate grants complete access to the signed applet, where does the fine-grained security professed in Java 2 come in?"

In fact, the model does not seem a whole lot different from version 1.1. However, the plug-in default behavior can be overridden by specifying a new permission named usePolicy under RuntimePermission in the policy file. The pop-up dialog box serves a useful role for unsophisticated users and for temporary exceptions to the installed policy, but only at the sole discretion of the user.

Figures 10 and 11 show the applet running in Netscape Navigator on Solaris and Internet Explorer on Windows, respectively.

Figure 10. Applet in Netscape Navigator
Click on thumbnail
to view full-size image (63 KB)



Figure 11. Applet in Internet Explorer
Click on thumbnail
to view full-size image (26 KB)



The applet may be run from http://www.javaworld.com/javaworld/jw-12-2000/security/writeFile.html.

The policy file's role

Let's remove the trusted certificate from the Java plug-in control panel to understand the role of the policy file. Select the certificate in the plug-in control panel and hit Remove. Close the control panel and bring it up again to ensure that the certificate has indeed been deleted.

We will look at several policy instances to understand the interaction of the plug-in and the policy file in making access-control decisions. We saw an instance where the user selected the security context since the policy file did not contain any relevant entries.

Let's modify the policy file to contain the entry below:

grant {
  permission java.lang.RuntimePermission "usePolicy";
};


Now, run the applet as before. Notice that the pop-up dialog box does not appear due to the permission usePolicy in the policy file. The applet generated a security exception since there was nothing specified in the policy file to permit that operation. To explicitly provide that permission, add an entry to the policy file:

grant {
  permission java.lang.RuntimePermission "usePolicy";
  permission java.io.FilePermission "C:${/}tmpfoo", "write";
};


As you might expect, rerunning the applet will create and modify the file without popping up the dialog box.

Finally, let's remove the usePolicy entry in the policy file:

grant {
  permission java.io.FilePermission "C:${/}tmpfoo", "write";
};


The dialog box pops up again as expected and, regardless of what security context is chosen in the dialog box, the file will be modified. In other words, it does not matter if access was granted or denied. Why? The installation's policy is ultimately governed by the policy file. The pop-up dialog box should be used very selectively, especially in situations where it might be unreasonable to expect the user to modify the policy file. My mom would be a good example of such a user. Hopefully, she will trust me enough to provide access to an applet that I have signed and let me out of the sandbox.

In summary, the Java plug-in checks for the permission entry usePolicy and will pop up the dialog box described earlier only if that entry is not present. If that entry is present, the plug-in quietly accords permission based on the installation's policy. The policy file entry can override the security decisions made by the plug-in, thus permitting greater access. Of course, if the code is not signed, it's confined to the sandbox.

Fine-tuning the policy file

In the examples above, the policy was set at a very coarse level. You may want to fine-tune the policy to incorporate the origin of the code and the signer, as we saw in the example with Java 2.1.2.

As a first step, import the public-key certificate into the keystore.

C:\signtool> keytool -printcert -file rags.cer
Owner: CN=Raghavan N. Srinivas, OU=Sun Microsystems (MDDR), O=Raghavan N. Srinivas, L=Burlington, ST=MA, C=US
Issuer: EmailAddress=server-certs@thawte.com, CN=Thawte Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
Serial number: 7c093
Valid from: Wed Dec 13 16:18:38 EST 2000 until: Fri Dec 21 17:20:22 EST 2001
Certificate fingerprints:
         MD5:  34:6C:32:F9:2E:0D:0D:B3:99:13:FC:EC:F3:D9:8B:AF
         SHA1: 77:5D:D9:EC:62:4D:C7:47:D9:58:05:73:B9:34:60:F6:38:A8:36:94
C:\signtool> keytool -import -file rags.cer -alias rags
Enter keystore password: 
Owner: CN=Raghavan N. Srinivas, OU=Sun Microsystems (MDDR), O=Raghavan N. Srinivas, L=Burlington, ST=MA, C=US
Issuer: EmailAddress=server-certs@thawte.com, CN=Thawte Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
Serial number: 7c093
Valid from: Wed Dec 13 16:18:38 EST 2000 until: Fri Dec 21 17:20:22 EST 2001
Certificate fingerprints:
         MD5:  34:6C:32:F9:2E:0D:0D:B3:99:13:FC:EC:F3:D9:8B:AF
         SHA1: 77:5D:D9:EC:62:4D:C7:47:D9:58:05:73:B9:34:60:F6:38:A8:36:94
Trust this certificate? [no]:  yes
Certificate was added to keystore


Change the key and the origin of the code in the policy file to look something like this:

C:\signtool> type c:\windows\.java.policy
/* AUTOMATICALLY GENERATED ON Mon Dec 04 21:19:33 EST 2000*/
/* DO NOT EDIT */
keystore ".keystore", "jks";
grant signedBy "rags" codeBase "http://www.javaworld.com/jw-12-2000/security/writeFile.jar" {
  permission java.lang.RuntimePermission "usePolicy";
  permission java.io.FilePermission "C:${/}tmpfoo", "write";
};


The keystore is relative to the URL of the policy file. In this particular case, the keystore file -- .keystore -- is in the same directory as the policy file.

As alluded to before, fine-grained policy can be achieved by according separate permissions based on the CodeSource that comprises both the signedBy and codeBase properties. In the example above, permissions to write a file on the local filesystem are provided to the code based on its signature and its origin. Similarly, other permissions can be accorded in the policy file.

Automatic deployment of policy files

Looking at the role of policy file above, it seems like a chicken and egg problem -- if we could only modify the policy files, the policy files could then provide the optimal access to an applet that we deploy. It's unreasonable to expect unsophisticated users to modify their policy files. The user has to provide initial access for the applet to be able to modify the policy file anyway. Assuming this happens -- that is, even if the user grants access just for the session -- the applet can modify the policy file to provide the appropriate level of access to itself without popping up the dialog box in the future.

Given all this, is it a reasonable approach for an applet to modify the policy file directly without informing the user? I personally think that approach is akin to sneaking up behind an unsuspecting friend. The approach may not always work, especially when a similar approach is used by more than one applet. Also, the user may always modify the policy file explicitly in the future, invalidating some of the changes made. You may also lose some friends and business due to your covert action.

A more acceptable approach might be to deploy a separate applet that informs the user and updates the policy file with his or her consent, clearly outlining the potential risk in the operation. Since the initial step can happen only with the permission of the user, it's a reasonable way to work with the user to modify the policy file -- the applet aids the user in providing the necessary permissions via the policy file.

In intranet scenarios, separate policy files can be maintained for each applet. These can be added to the ${java.home}lib/security/java.security file via an entry which looks like this:

policy.url.3=http://www.javaworld.com/javaworld/jw-12-2000/security/writeFile.policy


For a Solaris or Linux system, add the following entry:

policy.url.3=http://www.javaworld.com/javaworld/jw-12-2000/security/writeFile-unix.policy


The writeFile.policy file's contents are:

/* AUTOMATICALLY GENERATED ON Fri Nov 10 17:07:18 EST 2000*/
/* DO NOT EDIT */
keystore "writeFile.keystore", "jks";
grant signedBy "rags" codeBase "http://www.javaworld.com/jw-12-2000/security/writeFile.jar" {
  permission java.lang.RuntimePermission "usePolicy";
  permission java.io.FilePermission "C:${/}tmpfoo", "write";
};


Correspondingly, the file contents of writeFile-unix.policy are:

/* AUTOMATICALLY GENERATED ON Fri Nov 10 17:07:18 EST 2000*/
/* DO NOT EDIT */
keystore "writeFile.keystore", "jks";
grant signedBy "rags" codeBase "http://www.javaworld.com/jw-12-2000/security/writeFile.jar" {
  permission java.lang.RuntimePermission "usePolicy";
  permission java.io.FilePermission "/tmp/foo", "write";
};


after the policy.url.1 and policy.url.2 entries. This policy will affect multiple users that run the plug-in from the same path. The content of all the policy files will be used to administer the overall policy.

Conclusion



In earlier articles, we discussed the different aspects of Java security, starting with its evolution. This article aimed to combine the concepts presented earlier with get-your-hands dirty applet code, a frequently misunderstood aspect of Java security. As we've seen, by signing the code once, the applet can be run identically on a variety of operating systems -- Linux, Solaris, and Windows -- and under a variety of browsers and browser versions. Keep in mind that code signing should not be construed as a silver bullet to solving all security problems. It's a critical link in the whole security chain.

In my next article in this series, I'll discuss the Java Security extensions, also referred to as optional packages. I'll also touch upon the Java 2 Platform, Enterprise Edition (J2EE) and RMI security, both of which take a different approach to security. Under these schemes, it is no longer left to the developer to assemble the building blocks to provide security; instead, the developer and the deployer share responsibility in providing overall system security with lesser emphasis on programming and more emphasis on customization via a declarative model.

About the author

Raghavan Srinivas is a Java technology evangelist at Sun Microsystems who specializes in Java and distributed systems. He is a proponent of Java technology who teaches graduate and undergraduate classes in the evening. Srinivas holds a master's degree in computer science from the Center of Advanced Computer Studies at the University of Southwestern Louisiana. He likes hiking, running, and traveling, but most of all loves to eat, especially spicy food.
  • Print
  • Feedback

Resources