In this blog post I will explain the different types of Oracle wallet with the auto_login feature.

What is an Oracle Wallet

An Oracle wallet is used to store certificates for Listeners with https protocol, or it can be used as an encrypted password store for Oracle logins.

Technically, an Oracle wallet is an encrypted, password-protected PKCS#12 container file (ewallet.p12) that also can be accessed with openssl tools to show and extract keys and certificates.

openssl pkcs12 -nokeys -info -in ewallet.p12

Storing credentials (user/password/tns_alias) in an Oracle wallet is a proprietary extension from Oracle which is not understood by openssl.

Secret bag
Bag attributes
    localKeyID: AA BB CC DD ....
Bag Type: 1.2.840.113549.1.16.12.12
Bag Value: <Unsupported tag 16>

Generally, do not modify an Oracle wallet with openssl tools! To work with Oracle wallets, use the orapki or mkstore utilities in $ORACLE_HOME/bin;

Auto-login Wallets

The PKCS#12 file (ewallet.p12) is password protected. To startup SSL Listeners or to login with sqlplus or dgmgrl to a database non-interactive (without a password prompt), a different wallet-type is required, a so-called auto_login* wallet.

How does that work? Oracle creates a proprietary shadow-file of the ewallet.p12 file, the cwallet.sso; Oracle tools like sqlplus or tnslsnr have access to this proprietary file without the need of a password. Security is primarily based on filesystem permissions and a blackbox file structure of the cwallet.sso. Not very secure, but even better than cleartext passwords in files.

For this auto-login feature, there are 3 additional wallet-types (2-4):

  1. The normal wallet without auto-login (ewallet.p12)
  2. The auto_login wallet (ewallet.p12, cwallet.sso)
  3. The auto_login_local wallet (ewallet.p12, cwallet.sso)
  4. The auto_login_only wallet (cwallet.sso)

To create the wallets, use the orapki command

orapki wallet create -wallet .  #create a wallet in the current directory (non-auto-login)
orapki wallet create -wallet .  -auto_login
orapki wallet create -wallet .  -auto_login_local
orapki wallet create -wallet .  -auto_login_only

auto_login_only

The auto_login_only wallet is a special case. There is no PCKS#12 container, and you have access to the content without a wallet-password. So you can extract user-credentials in cleartext or private keys without a password! So do not use auto_login_only to store user-certificates/private-keys or credentials. This type of wallet is intended to only store trusted (public) certificates, required to initialize SSL connections to a remote site.

auto_login and auto_login_local

The auto_login and auto_login_local wallet contains both the ewallet.p12 and the cwallet.sso file. To modify the wallet, the wallet password must be provided. orapki then updates both files.

The difference of the two wallet types are that the auto-login feature of the auto_login_local wallet can only be used on the host it was created and and by the user who created the wallet. But do not confuse: the ewallet.p12 file can be accessed with the wallet password on other systems or by other users. The difference is in the cwallet.sso file.

The auto_login_local wallet should be used for server certificates (in orapki named user_certificate) The server certificate should not be used on another host.

Determine the wallet-type

To see which wallet type is on a system, that is a bit tricky. Oracle tools will not show the wallet type. If there is only a cwallet.sso, but no ewallet.p12 file, then it is probably an auto_login_only wallet. But: it is also possible that someone only copied the cwallet.sso file from another system. That works for auto-login, but you can no longer modify the wallet. To test, use mkstore -wrl . -listCredential; if it asks for a password, it is not an auto_login_only wallet.

And to see if it is a auto_login_local or auto_login (global) wallet you have to copy it to another host and see if the auto login feature still works or not.

But is there a better way than such try-and-error methods?

Yes! use the od (octal dump) utility and analyze the first line.

od cwallet.sso | head -n 1 

I used different ORACLE_HOME’s and created with each home 2 wallets of the same login type and compared the output. Then, I identified the third number group of the first line to be constant for the same type of wallet and different for another type of wallet. E.g. for an auto_login_local wallet it is always 034116.

0000000 174241 034116 000000 003000 000000 020400 012406 010137 #auto_login_local
0000000 174241 033116 000000 003000 000000 020400 033406 125027 #auto_login (global)
0000000 174241 033516 000000 003000 000000 020400 065406 020030 #auto_login_only

Hint: the output is dependent of the endianness of the system. On X86 architecture with little-endian (example above), the od output of an auto_login_local wallet is “034116”, on a big-endian system (e.g. AIX) it is “047070”. If you copy the cwallet.sso from an AIX system to Linux, you will get the same number group as from a Linux wallet. So the output is dependent on the platform where od is called, and not on the platform where the wallet was created. Below you can see the output of a big-endian system:

0000000  120770 047070 000000 000006 000000 000041 003313 117047 #auto_login_local
0000000  120770 047066 000000 000006 000000 000041 003321 045646 #auto_login
0000000  120770 047067 000000 000006 000000 000041 003047 065254 #auto_login_only

To get the wallet-type, you can use the following shell-script code

  if [ -f cwallet.sso ]; then
    autologincode=$( od cwallet.sso |head -n 1 | awk '{print $3}' )
    echo autologincode=$autologincode
    case $autologincode in
      047066|033116) type="auto_login (global)"; test -f ewallet.p12 || type="$type, but ewallet.p12 is missing" ;;
      047067|033516) type="auto_login_only";     test -f ewallet.p12 && type="$type, but unknown ewallet.p12 present" ;;
      047070|034116) type="auto_login_local";    test -f ewallet.p12 || type="$type, but ewallet.p12 is missing" ;;
      *) echo "unknown" ;;
    esac
    echo "Wallet-type is $type"
  elif [ -f ewallet.p12 ]; then
    echo "Wallet-type is without autologin"
  else
    echo "No Oracle wallet in this directory"
  fi

Converting wallets

To convert an auto_login or auto_login_local wallet to a non-auto-login wallet: simply remove the cwallet.sso file.

As long as the ewallet.p12 file exists, it can be converted to an auto_login or auto_login_local wallet

orapki wallet create -wallet . -auto_login 
orapki wallet create -wallet . -auto_login_local

But you can not create an auto_login_only wallet from another wallet type (existing ewallet.p12). The error-message is PKI-02001: A wallet already exists at: .

And to create an auto_login(_local) wallet from an auto_login_only wallet? The command above for conversion works. The type is changed to auto_login, but: Oracle forgets to create the ewallet.p12 file. As a result, you have a wallet that can no longer be modified! 🙁

With Oracle tools it seems not to be directly possible, you have to rebuild the wallet. Certificates can be moved by export/import, but credentials have to be re-added manually.

To move the certificates, first, convert the proprietary cwallet.sso file to a jks keystore.

read PW  # type the password (it is not stored in the shell-history)
orapki wallet pkcs12_to_jks \
  -wallet . \
  -jksKeyStoreLoc ewallet.jks \
  -jksKeyStorepwd $PW

Then, you can convert the jks to a p12 file

mkdir new_wallet/
keytool -importkeystore \
    -srckeystore ewallet.jks \
    -srcstoretype JKS \
    -srcstorepass "$PW" \
    -destkeystore new_wallet/ewallet.p12 \
    -deststoretype PKCS12 \
    -deststorepass "$PW"

If it only contains trusted certificates, it can be converted to an Oracle auto_login wallet:

orapki wallet create -wallet new_wallet/ -pwd $PW -auto_login  #or -auto_login_local
orapki wallet display -wallet new_wallet/   #should now work without password

But if it also contains “User Certificates” (server certificate and private key), you can use the command above and it looks like an auto_login wallet. But: It ignores the auto-login part, it always asks for a password! 🙁

To transfer the user certificate, you have to import it in an empty Oracle wallet

cd new_wallet
mv ewallet.p12 container.p12
rm *wallet.*
orapki wallet create -wallet . -auto_login   #create a new, empty wallet
orapki wallet import_pkcs12 -wallet . -pwd $PW -pkcs12file container.p12 -pkcs12pwd $PW

Afterwards, we have a working auto_login wallet with the user certificate and some, but probably not all, trusted certificates. Import the missing trusted certificates afterwards

orapki wallet add -wallet . -cert Pcs3ss_v4.pem -trusted_cert  -pwd $PW

Summary

The auto-login feature of Oracle wallets, which is implemented by the proprietary cwallet.sso file, enables non-interactive logins and startup of SSL Listeners within the Oracle world, e.g. for batch processing.

For security reasons, keep an eye on the filesystem permissions. If possible, restrict the access to the owner only (oracle, chmod 600). If there is no need to copy wallets to different servers, use the auto_login_local wallet type. The advantage is that if someone copies the cwallet.sso file to another host, it can not use the auto-login feature.

The auto_login_only wallet is a good solution to store trusted certificates (which are publicly available). Use-case is a wallet for client-connects with TCPS and no need for client-authentication.

All wallet-types, except auto_login_only, can be converted with orapki from each type to another.

Converting an auto_login_only wallet is partially possible with a combination of openssl- and Oracle tools.