Re: getSigners() in java.lang.Class

Roland Schemers (Roland.Schemers@Eng)
Thu, 21 May 1998 12:19:06 -0700 (PDT)

Message-Id: <199805211919.MAA10568@crypto.eng.sun.com>
Date: Thu, 21 May 1998 12:19:06 -0700 (PDT)
From: Roland Schemers <Roland.Schemers@Eng>
Subject: Re: getSigners() in java.lang.Class
To: java-security@web2.javasoft.com, rpenny@gensym.com

>
> What is the purpose and level of implementation of this method? The
> javadoc is very scanty, and I could find no references to this method in
> a 2-hr scan of jdk security documentation. I am currently running
> jdk1.1.5 and developing an application using JNI and RMI. I have the
> following problem: I wish to be able to ensure that certain licensing
> checks in our application are not defeated by customers who might
> decompile our java code and work around our licensing checks. I was
> wondering if there would be some way from within the C code (harder to
> decompile) that we could check that certain objects are from untampered
> classes.

In JDK 1.1.x, getSigners will return an array of Identity objects,
representing the identities that signed the class. In JDK 1.2beta4,
getSigners will return an array of java.security.cert.Certificate
objects.

> I looked at the idea of using getSystemResourceAsStream to check that
> the bytes used to define the class were OK (would feel most secure if
> the classes had been loaded by the system class loader), but since this
> appears not to be allowed for class files (I got a security exception
> along the way) I am researching whether or not I can use jar signing as
> another form of security check. It seems on the surface that being able
> to call obj.getClass().getSigners() or something from within native code
> would be a good start: maybe we would be able to pass in a public key to
> some object to ensure that it had the right private key, thus ensuring
> that the class was loaded from our signed jar. Or something (I'm a
> little new to this whole security field).
>
> However (to avoid the possibility that I made a mistake in signing a jar
> since I am new to javakey), I used the signedWriteFile.jar from
> ftp://ftp.javasoft.com/docs/security/signExample/signedWriteFile.jar
> and tried:
>
> package security;
>
> public class Test {
> public static void main(String[] args) {
> try {
> Class clazz = Class.forName("writeFile");
> System.out.println("class=" + clazz + ";signers=" +
> clazz.getSigners());
> } catch (Exception ex) {
> ex.printStackTrace();
> }
> }
> }
>
> The output was:
>
> c:\>java security.Test
> java security.Test
> class=class writeFile;signers=null
>
> It appears that the SystemClassLoader does not call setSigners(), even
> when loading from a signed jar.

Correct. The system class loader is written in C, and is used to bootstrap
the system. It doesn't understand signing. Also note that in order for the
class to be signed it must be placed in a jar file.

In JDK1.2 you can do something like:

java -classpath foo.jar security.Test

And it will verify signatures on the classes loaded from foo.jar. That
is because 1.2 actually uses a class loader now to load things off of
the classpath.
>Even if we were to implement our own
> class-loader and call setSigners() ourselves, how could we know that our
> own class-loader hadn't been tampered with?

you can't. How do you know that the VM itself hasn't been tampered with?
Or the OS running the VM? Its not an easy problem. Anyone who can
write a native method can set the signers on a class. I think you can
use signing to reasonably increase the efforts someone has to go through
to get around your checks, but in the end you can't make it bullet-proof
unless you have tight control over the VM that is running the code.

> Lacking documentation that pointed a way to solving my particular
> problem, I have tried the naive interpretation of what little
> information I could find. That having failed (and the archives of this
> list having nothing obvious on the subject), I am trying the more direct
> approach of asking :-)
>
> Thanks for your help,
> -Robert

Why not have the C code (since you have C code) do the license checks instead of
the Java code?

hope that helps.

roland