Wednesday Apr 22, 2009

Fedora 10

Trying to install it again. Last time (probably F8) it does not support GUI login as a NIS user. GDM hangs.

Hope it's fine now. Will see if it's a better system building OpenJDK.

Update: NIS account can login, no +::: lines needed. However, system goes unstable when trying to change network setting to manual IP. Re grub-install and now back in Ubuntu.

Anyway, OS is there now, might try again someday.

Monday Apr 20, 2009

Several Enhancements for JarSigner

There're several enhancements to the jarsigner tool in OpenJDK lately.

First, jarsigner accepts a new option -certchain file to use a certificate chain in an external file. People can using PKCS #11 tokens to store their private keys. Some of these tokens are so small that there's no place to store the certificate chain inside it. Although you can access it with a KeyStore.getInstance("pkcs11"), the getCertificateChain() method returns nothing. Now you can use jarsigner with this kind of tokens, using the token as the keystore, but point your certchain to another file that contains the full chain.

Second, people see jarsigner showing warnings now and then, like certificate expired, or keyusage not correct. if they want to know this information if jarsigner is called in a script, they can only grep the words. Now, if you add a new option -strict, not only the warnings will be printed, a System.exit(n) is called when there is/are warning(s). Here, n is a binary sum of these pre-defined warning codes:
  • 2: hasExpiringCert
  • 4: chainNotValidated (including hasExpiredCert, notYetValidCert)
  • 8: Usages problems (including badKeyUsage, badExtendedKeyUsage, badNetscapeCertType)
  • 16: hasUnsignedEntry
  • 32: notSignedByAlias or aliasNotInStore
Noticed the new warning type notSignedByAlias? Now you can call jarsigner -verify jarfile alias0 alias1... with zero+ of aliases to check if certificates of the signed entries inside the file match any of these aliases.

Third, people complain jarfiles show too little or too much output at verifying. If you simply verify a jarfile, it might tell you some warnings, call with -verbose -certs to read details. You verify again with those two options on, and huala... thousands of lines fly through and you cannot catch a word. Now -verbose has sub options so you can precisely tell it how verbose the output should be:
  • -verbose:all, this is the default -verbose, which shows as much information as it did
  • -verbose:grouped, this shows less information. The entries with the same signer info are grouped together. This means the names of the entries are listed together, with the signer info only printed once. Something like this:
          smk   A.class
          smk   B.class
          Certificate A (CN=A, OU=B)
  • -verbose:summary. This is the simplest one. Besides grouping the entries with same signer info together, not all the entry names are printed, but only one line of summary. Something like this:
    smk   A.class (and N-1 more)
          Certificate A (CN=A, OU=B)
    Using this option, unless your jar file is signed by dozens of different signers, no matter how many entries inside, the output should not exceeds two screens.

Monday Feb 23, 2009

Another new keytool enhancement: -printcert -sslserver

Andreas has written a blog entry on retrieving certificates from an SSL server. Whenever I see someone asking this question on the Java forum I point the user to this entry. Now it's time for this function to be included in keytool.

Call keytool -printcert -sslserver to see what's shown.

During the implementation of this feature, there are some discussions on how the function should be called. Two topics are most interesting:

What's the function name? At first, the plan is to add a new function to import the certificate into a keystore. The command will look like "-importcert -sslserver". However, there came several problems:
  1. For a normal certificate file, you can first call -printcert on it, read carefully, and then decide if it can be imported. For a certificate from an SSL server, you can still call something like "-printcert -sslserver" on it, but do you dare call "-importcert -sslserver" after examining it carefully? No, because the SSL server is not controlled by you, and it might send out a different certificate in the second call. That's scary, isn't it?
  2. An SSL server sends you a certificate chain. If you want to import one that's not always the end-entity cert, you need to specify a position number. This means another option, more interactions, and, more error messages or IndexOutOfBoundException. That's not good.
So the command ends up with a simple "-printcert -sslserver". It's left to the user to read/check/cut/paste the info wanted.

What protocols to support? This is a simple question, and the answer is ALL. Every application protocol that's based on SSL is included. However, the implementation chooses only HTTPS, for several reasons:
  1. HTTPS is the most popular SSL-based protocol out there, and programming it is the easiest, I simply call
    new URL("https://" + sslserver).openConnection().connect();
  2. HTTPS supports proxy, so you can add -Dhttps.proxyHost and -Dhttps.proxyPort if the SSL server is behind a proxy.
  3. Last and the best. It also works for any SSL-based application protocol, because the handshake part of any such protocol is identical. Please notice that I only call the connect() method, where handshake is done but no application specific data communication is performed yet.

BTW, the feature was added into keytool long time ago.

keytool enhancements

Update: CRLDistributionPoints extension support added.
There're two enhancements made to keytool today (the doc has not been updated, it's still for JDK 6):

new commands and options

We have 2 new commands: -gencert, -printcertreq and 1 new option -ext. Read the RFE descriptions.

-printcertreq is simply for printing the content of a certificate request. It behaves like the -printcert command, reading a PKCS #10 format cert req from a file or stdin, and does not need a keystore to run with.

-gencert is a big enhancement, which means you can setup a tiny CA now with keytool. The command reads a certificate request from a file (specified by -infile) or stdin, creates a certificate, signs it with the private key in the PrivateKeyEntry specified by -alias, and print the output to another file (specified by -outfile) or stdout. That's it. Just like -genkeypair for self-signed certificate, you can specify -sigalg, -startdate, and -validity options to the command.

-ext is used to add X.509v3 certificate extensions to a certificate (for both -genkeypair and -gencert) or a certificate request (for -certreq). The option can be specified multiple times to add multiple extensions. The value of this option takes the form of name[:critical][=value]. Here name is the extension name, and value the value (omit if empty). The :critical modifier, if provided, means the extension's isCritical attribute is true; otherwise, false.

Currently we support these named extensions (case-insensitive):
BC or BasicConstraintsThe full form: "ca:{true|false}[,pathlen:len]"; or, "len", a shorthand for "ca:true,pathlen:len"; or omitted, means "ca:true"
KU or KeyUsageusage(,usage)\*, usage can be one of digitalSignature, nonRepudiation (contentCommitment), keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly. Usage can be abbreviated with the first few letters (say, dig for digitalSignature) or in camel-case style (say, dS for digitalSignature, cRLS for cRLSign), as long as no ambiguity is found. Usage is case-insensitive.
EKU or ExtendedkeyUsageusage(,usage)\*, usage can be one of anyExtendedKeyUsage, serverAuth, clientAuth, codeSigning, emailProtection, timeStamping, OCSPSigning, or any OID string. Named usage can be abbreviated with the first few letters or in camel-case style, as long as no ambiguity is found. Usage is case-insensitive.
SAN or SubjectAlternativeNametype:value(,type:value)\*, type can be EMAIL, URI, DNS, IP, or OID, value is the string format value for the type.
IAN or IssuerAlternativeNamesame as SubjectAlternativeName
SIA or SubjectInfoAccessmethod:location-type:location-value (,method:location-type:location-value)\*, method can be "timeStamping", "caRepository" or any OID. location-type and location-value can be any type:value supported by the SubjectAlternativeName extension.
AIA or AuthorityInfoAccesssame as SubjectInfoAccess. method can be "ocsp", "caIssuers" or any OID.
CRL or CRLDistributionPointssame as SAN. This means you can only add one point with only names

When name is an arbitrary OID, value is the HEX dumped DER encoding of the extnValue for the extension excluding the OCTET STRING type and length bytes. Any extra character other than standard HEX numbers (0-9, a-f, A-F) are ignored in the HEX string. Therefore, both "01:02:03:04" and "01020304" are accepted as identical values. If there's no value, the extension has an empty value field then.

A special name "honored", used in -gencert only, denotes how the extensions included in the certificate request should be honored. The value for this name is a comma-seperated list of "all" (all requested extensions are honored), "name[:{critical|non-critical}]" (the named extension is honored, but using a different isCritical attribute) and "-name" (used with all, denotes an exception). Requested extensions are not honored by default.

If, besides the -ext honored option, another named or OID -ext option is provided, this extension will be added to those already honored. However, if this name (or OID) also appears in the honored value, its value and criticality overrides the one in the request.

The subjectKeyIdentifier extension is always created. For non self-signed certificates, the authorityKeyIdentifier is always created.

Try this command on your system if you already have 2 self-signed certs me and ca created in your default keystore:
    keytool -storepass changeit -certreq -alias me -ext bc -ext eku=sa,ca | \\
    keytool -storepass changeit -gencert -alias ca -ext honored=all,-bc \\
        -ext aia=ocsp:uri:,cai:uri:  |
    keytool -printcert
Here, the user me requests for an SSL server certificate from the CA. It asks for an EKU extension named ServerAuth and ClientAuth, which is useful for an SSL server. However, it also secretly asks for a BC extension, so that it can start its own CA. The CA, with sharp eyes, notices this problem. It grants all extensions requested except BC. It also adds another extension AIA which includes issuer info into the cert generated.

openssl-style certificate support

When you run openssl x509 -text with an X.509 certificate, the output includes a bunch of human-readable texts before the BASE64-encoded certificate itself. Java did not accept these texts and threw an exception something like "unknown tag or bad length", since it tried to interpret the file as DER encoded. Now we enhance the X.509 CertificateFactory class to accept this kind of certificate.

By the way, have I mentioned -startdate before? This option allows you to change the issuing time of a certificate from current system time to something else. Some people may like this option to create certs for special test cases, and some other people would like the certificate to have an earlier time because they want to use it right now but their clients and servers are not precisely time-synchronized. The grammar for this option takes one of the 2 following formats:
  1. ([+-]nnn[ymdHMS])+
  2. [yyyy/mm/dd] [HH:MM:SS]
So -startdate -5M means 5 minutes ago, -startdate "2001/01/01 11:11:11" means that exact time, -startdate 11:11:11 means that time today. Read more in the RFE decriptions.

Wednesday Jan 21, 2009

Small Enhancements to HGrev

I've enhanced a little. Now the patch view has links to previous and new codes in raw form, so that you can download it directly to try on your own computer.

Monday Jan 19, 2009

Who Moved My krb5.ini?

Java Kerberos 5, on Windows, looks for a config file named krb5.ini in the Windows directory, and a Windows directory is defined as the return value of the Win32 API GetWindowsDirectory(), which should normally return something like C:\\Windows.

But, since Windows Server 2003, something has changed. The Terminal Services Programming Guidelines has these words: In a Terminal Services environment, the Windows directory is guaranteed to be private for each user.

So this means if your (post Windows 2003) system has Terminal Services turned on, Java would look for krb5.ini inside %YOUR_HOME%\\Windows. This is bad, since we believe that the Kerberos 5 setting is a system-wide configuration, which should be setup once for all. To fix this problem, we make some changes in the OpenJDK codes. From now on, Java will look for krb5.ini in both GetWindowsDirectory() and GetSystemWindowsDirectory(),

  1. Why is GetWindowsDirectory() still called? why is it even preferred to GetSystemWindowsDirectory()?
    There are two reasons. First, compatibility matters. It is very possible that users out there have already noticed this issue and have put krb5.ini inside the user-private Windows directory instead of the system-wide one. For these users, JDK 7 should still work for them. Second, it's a common sense that user settings should override system settings. Therefore, user-private Windows is preferred to system-wide Windows.
  2. I'm still using JDK 6 and I don't like this user-private Windows directory, what shall I do?
    There are three solutions. First, you can provide the option to your Java command line, or setup the environment variable _JAVA_OPTIONS to contain this value. Second, the most preferred Kerberos 5 config file is krb5.conf inside [JRE]/lib/security. Use this file is always safe (Note: it's krb5.conf, not krb5.ini). Third, you can trick the Windows to still return C:\\Windows for GetWindowsDirectory(). To do this, add a registry key HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Terminal Server\\Compatibility\\Application\\JAVA, with a 32-bit DWORD value Flags=0x408. If you want to use Java's Kerberos command kinit, klist etc, provide keys with the name KINIT, KLIST etc.
P.S.: A minor Windows 2008 bug (or maybe not a bug, see below) makes this problem a little tougher. On Windows Server 2008, GetWindowsDirectory(NULL,0) returns the length of the system-wide directory, but not the user-private one. Thus our original trick of get-length-then-allocate-then-get-value fails, and JDK 6 cannot locate the correct user-private Windows directory. If you met this problem, you would have to choose one of the three workarounds above. MSDN never says the first parameter of this API can be NULL, although quite a lot of people are using the same trick.

The positive side is, we always print out the pathname of the krb5.ini file we're using in the debug output. Just add the option to your java command line to make sure it's using the krb5.ini of your intention.

Friday Jan 16, 2009

NetBeans C++ is Cool

Although I use NetBeans a lot writing Java, I've never really tried its C/C++ Pack before. Today I need to read some MIT Kerberos codes. There's a long time I haven't worked heavily on C so I find it quite difficult to find out which function does what and where it's defined. And then, I think of NetBeans, it's very good at parsing Java codes and give you multiple ways to navigate through the method calls and field definitions. How about trying it for C?

So I fire up NetBeans and go download the C/C++ pack. It's a huge 5MB module that takes care of projects, editing, debugging all in one place. Install and restart.

I create a C/C++ project, there's a choice called "Use existing codes" so I choose the Kerberos src directory and click go. The magic happens: it loads all the files inside the directory, and then starts to call the configure script, and I see yes/no lines flying in the output window. Then, it starts to build the source! With no human intervention, it does everything from the beginning to the end, and I'm now seeing MAKE SUCCESSFUL.

Brilliant, isn't it? I open a terminal window and run the newly-built kinit command with DYLD_LIBRARY_PATH pointing to the lib directory, and it runs smoothly and correctly, showing the kinit help page.

Now I'm browsing the Kerberos codes, using the familiar Command+click to go through function calls and variable definitions. A real charm!

Thursday Jan 08, 2009

Picasa for Mac

I'm happy to become a Picasa user again. For the last two years, I use Finder and Preview to take care of all my photos. It's a very difficult job - I leave quite some duplicates here and there, and I dare not edit photos except rotating them. I hate iPhoto, I don't want the files be moved to somewhere else, and I feel bad when I don't know what it's doing and how it stores things.

Now I can do the so-called non-destructive edit again. Picasa for Mac still recognizes all previous edit made in Windows, the Picasa.ini file I mean. It would update the file if you make more edit. When there's no Picasa.ini, it happily creates a .picasa.ini file, which is the standard Unix style to name a hidden file.

I believe Picasa for Windows will recognize .picasa.ini also.

Wednesday Jan 07, 2009

OpenSolaris on Bare Metal

Finally I decide to install OpenSolaris on the bare metal, and probably use it as a nightly build machine.
  1. Create a USB installer using usbcopy
  2. Boot from this USB disk and install
  3. Reboot, disable network/physical:nwam, enable multicast and network/physical:default, call sys-unconfig
  4. Reconfigure the machine
  5. Reboot again
I hadn't enabled/disabled the services first time when I run sys-unconfig, and the machine cannot reboot complaining avahi-bridge-dsd cannot start. Fortunately I can login to single user mode and do that again.

I'm learning how to give more privileges to my NIS user account now.

Wednesday Dec 17, 2008

mechListMIC in SPNEGO

I try hard to understand when should mechListMIC be generated in SPNEGO, but still find the specification (RFC 4178) confusing. I'd like to interpret it this way:
  • If the chosen mech is the first one in the list, don't bother to create it
  • Generate the MIC whenever you think you can do it, i.e. mech's isEstablished() is true
  • Response to a MIC whenever you receive one
In case you believe the incoming token should have the MIC but it hasn't, if it's already marked COMPLETE, you go COMPLETE also. Otherwise, it may be expecting a MIC from you, either create the MIC and send back, or send back an empty COMPLETE.

OK, I admit I don't understand it.

Tuesday Sep 09, 2008

Mark Bristow, Today's Gold Medalist

Silicon Valley? That's Sun Microsystems.


Tuesday Aug 26, 2008

LiveCD of OpenSolaris in VMWare

Normally I don't like running an OS as a LiveCD on a bare metal machine because accessing CD-ROM is too slow and makes very big noises. However as a VMWare guest, since the CD-ROM is in fact an ISO file on the hard disk, I guess the speed should be quite fast, I'm quite happy to only run it on the LiveCD.

So I creates a new Virtual machine with two CD-ROM drives, put the LiveCD in the 1st one and the VMTools into the 2nd. When the system CD boots up, I will be able to install VMTools from the 2nd CD.

This works quite fine for Ubuntu and the VMTools is installed correctly. But for OpenSolaris 2008.05, it cannot be installed, because the file system that contains /usr is not writable.

I guess in Ubuntu the /usr volume is implemented as a cascaded/hybrid file system, most of the files are from the CD, but you can still add/remove/modify files into the memory that shadows the ones on the CD, and this combined file system looks like a single unified one. OpenSolaris should works the same way, I guess it's only that the designers didn't realize that /usr needs to be modified, so they never make this volume cascaded/hybrid.

Monday Aug 04, 2008

F9 (Compile) for NetBeans Missing

Just downloaded the latest DEV version of NetBeans, haven't done it for several weeks.

One thing that confuses me is that F9 seems does not work for individual files in a Java project anymore. Pressing F9 has no impact, the edited Java file still shows an asterisk sign in the editor pane header, still dirty, not even saved. Looking at the right mouse menu of the file, and the compile item is grayed not completely.

Strange, isn't it? Then I suddenly realized this might be because of the newly introduced compile-on-save feature. I try to add some runtime error into my Java file and save it. Run, failed! So my guess is correct.

Anyway, I'm still a little uneasy with this feature. When I save the file, if there's any compile-time error, how can I know the compilation failed? I may not have noticed the red lines or the red exclamation mark on the file node. And worse, the output pane does not popped up showing the compilation error info. (Yes, I normally hide it. Off topic, people invent more and more wide screens, why not higher?)

There should be a more friendly way here, right?

Thursday Jun 12, 2008

my webrev experiment: public, interactive and easy

Inside Sun, we use webrev to do code reviews, you can see an example here.

Well, there're several reasons I don't like webrev very much:
  • It's a pile of static files, you must first create them, and upload them to a public website (possibly one by one).
  • It used to be a nice archive of what you've done, but now in Mercurial we already have changesets.
  • It includes no interactive review process
OK, only the first reason is real. I just cannot resist the temptation to create a list.

Recently I've done some experiments on creating a new review style which is meant to be:
  • Public, the patch can be created and reviewed by anyone
  • Easy, creation and viewing are both very easy
  • Richer interaction, request and review can be done interactively along with the patch
I'm using the Google App Engine for a prototype called hgrev. The current implementation is already public and easy. By using the Google Accounts system, I believe the richer interaction should be fairly easy to add. Now it runs in a create-only mode, which means after you create a hgrev request, it cannot be modified anymore. This is not a bad idea before the accounts system is used.

To create a hgrev, you need to provide three info:
  1. A title, possibly a synopsis of a bug item
  2. The base URL, a public accessible URL that your patch is based on. If you're working on 2 patches at the same time on a single file, sorry. Maybe one day the base URL can be also another hgrev request.
  3. The patch itself, which is the raw output of "hg diff". Or if you use Mercurial Queue, the raw content of the patch file.
After you enter these information, a new hgrev request is created, you can send the URL of the request to anyone you ask for a code review. The reviewer can read the patch itself, or read a side-by-side comparison of each file before/after the patch. Since you've already provided the base URL, the reviewer can go back to the Mercurial code repository to read related codes etc.

Take a try at, I've already included several examples there.

By the way, if the webpage does not work with IE or any other web browser, that's my fault.

Thursday Jun 05, 2008


Just write a long web page using location.replace to move around to different corners of it. Find out these incompatibilities between different browsers:
  • Firefox is fine
  • Opera and WebKit save a history item for each replace call, which I don't like
  • IE is not aware of javascript-generated anchors

This blog has a comments managing system that requires me to approve each comment manually. Please do not re-post and I will reply it (if I have an answer) when I get pinged.


Top Tags
« March 2015