« REST APIを用いてOracle Database Cloud Serviceインスタンスを作成する | メイン | Oracle Database 10gの資格がINACTIVE(失効)に »

UTL_HTTPでHTTPS通信 / ORA-29024の回避

Oracle Databaseで定義済みPL/SQLパッケージに、HTTP通信を行うUTL_HTTPパッケージがあります。 エントリ オンプレミスのOracle DatabaseからOracle Database Cloud Serviceを作成する では、UTL_HTTPを用いて、Oracle Database Cloud ServiceのREST APIエンドポイントにアクセスし、Oracle Database Cloud Serviceインスタンスを作成しました。

Oracle Database Cloud ServiceのREST APIエンドポイントは、HTTPSを用いています。 このため、UTL_HTTPでHTTPSしたいわけですが・・・

SQL> declare
  2    ORACLECLOUD_USER      VARCHAR2(4000) := 'ryota.watabe@cosol.jp';
  3    ORACLECLOUD_PWD       VARCHAR2(4000) := 'password_string';
  4    ORACLECLOUD_IDDOMAIN  VARCHAR2(4000) := 'jpcosolxxxx';
    :
 78  end;
 79  /
declare
*
行1でエラーが発生しました。:
ORA-29273: HTTPリクエストに失敗しました ORA-06512:
"SYS.UTL_HTTP", 行1130
ORA-29024: 証明書の検証に失敗しました ORA-06512:
行48


SQL>

「ORA-29024: 証明書の検証に失敗しました」で実行に失敗してしまいました。

実は、UTL_HTTPでHTTPSを使用するには、接続先サーバのSSLサーバ証明書を検証するためのルートCA証明書が必要になります。

このプロシージャは、Secure Sockets Layer(SSL)、つまりHTTPSを経由するHTTP要求すべてに使用するOracle Walletを設定します。UTL_HTTPパッケージがSSLを介してHTTPサーバーと通信する場合、HTTPサーバーは認証局が署名したデジタル証明書をUTL_HTTPパッケージに示し、身分を証明します。Oracle Walletには、UTL_HTTPパッケージのユーザーが信頼する認証局のリストが含まれています。Oracle Walletは、HTTPS要求を作成するために必要です。

このため、以下の手順を実行します。

  1. orapki wallet createコマンドで(空の)Oracleウォレットを作成する
  2. ルートCA証明書cacert.pemを入手する
  3. cacert.pemをOracleウォレットにインポート可能な形式に変換する
  4. orapki wallet add -trusted_cert -cert コマンドでOracleウォレットにルートCA証明書を追加する
  5. OracleウォレットをOPENして、UTL_HTTPでHTTPSアクセスする

1. Oracleウォレットを作成する

orapki wallet createコマンドで(空の)ウォレットを作成します。

$ ORACLE_WALLET_PATH=/var/tmp/wallet
$ ORACLE_WALLET_PWD=WalletPasswd123
$
$ mkdir -p ${ORACLE_WALLET_PATH}
$ orapki wallet create -wallet ${ORACLE_WALLET_PATH} -pwd ${ORACLE_WALLET_PWD} -auto_login
Oracle PKI Tool : Version 11.2.0.3.0 - Production
Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.

$

2. ルートCA証明書cacert.pemを入手する

Mozilla.orgで配布している(おそらくFirefoxに組み込まれている)ルートCA証明書を変換したファイルが http://curl.haxx.se/ca/cacert.pem にあるため、これをダウンロードします。

$ wget http://curl.haxx.se/ca/cacert.pem
--2015-12-11 12:03:46--  http://curl.haxx.se/ca/cacert.pem
Resolving curl.haxx.se... 80.67.6.50, 2a00:1a28:1200:9::2
Connecting to curl.haxx.se|80.67.6.50|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 256338 (250K)
Saving to: `cacert.pem.1'

100%[======================================>] 256,338      144K/s   in 1.7s

2015-12-11 12:03:48 (144 KB/s) - `cacert.pem.1' saved [256338/256338]

$

3. cacert.pemをOracleウォレットにインポート可能な形式に変換する

ダウンロードしたcacert.pemは、複数のルートCA証明書が結合された形式です。 この形式ままOracleウォレットにインポートしようとすると、先頭のルートCA証明書しかインポートされないため、 ウォレットにインポート可能な形式に変換します。具体的には、結合された複数のルートCA証明書を、別々のファイルに分解します。

$ awk '
>   split_after == 1 {n++;split_after=0}
>   /-----END CERTIFICATE-----/ {split_after=1}
>   {print > "cert" n ".pem"}' < cacert.pem
$ ls cert*.pem
cert100.pem  cert124.pem  cert148.pem  cert33.pem  cert57.pem  cert80.pem
cert101.pem  cert125.pem  cert149.pem  cert34.pem  cert58.pem  cert81.pem
cert102.pem  cert126.pem  cert14.pem   cert35.pem  cert59.pem  cert82.pem
cert103.pem  cert127.pem  cert150.pem  cert36.pem  cert5.pem   cert83.pem
cert104.pem  cert128.pem  cert151.pem  cert37.pem  cert60.pem  cert84.pem
cert105.pem  cert129.pem  cert152.pem  cert38.pem  cert61.pem  cert85.pem
cert106.pem  cert12.pem   cert15.pem   cert39.pem  cert62.pem  cert86.pem
cert107.pem  cert130.pem  cert16.pem   cert3.pem   cert63.pem  cert87.pem
cert108.pem  cert131.pem  cert17.pem   cert40.pem  cert64.pem  cert88.pem
cert109.pem  cert132.pem  cert18.pem   cert41.pem  cert65.pem  cert89.pem
cert10.pem   cert133.pem  cert19.pem   cert42.pem  cert66.pem  cert8.pem
cert110.pem  cert134.pem  cert1.pem    cert43.pem  cert67.pem  cert90.pem
cert111.pem  cert135.pem  cert20.pem   cert44.pem  cert68.pem  cert91.pem
cert112.pem  cert136.pem  cert21.pem   cert45.pem  cert69.pem  cert92.pem
cert113.pem  cert137.pem  cert22.pem   cert46.pem  cert6.pem   cert93.pem
cert114.pem  cert138.pem  cert23.pem   cert47.pem  cert70.pem  cert94.pem
cert115.pem  cert139.pem  cert24.pem   cert48.pem  cert71.pem  cert95.pem
cert116.pem  cert13.pem   cert25.pem   cert49.pem  cert72.pem  cert96.pem
cert117.pem  cert140.pem  cert26.pem   cert4.pem   cert73.pem  cert97.pem
cert118.pem  cert141.pem  cert27.pem   cert50.pem  cert74.pem  cert98.pem
cert119.pem  cert142.pem  cert28.pem   cert51.pem  cert75.pem  cert99.pem
cert11.pem   cert143.pem  cert29.pem   cert52.pem  cert76.pem  cert9.pem
cert120.pem  cert144.pem  cert2.pem    cert53.pem  cert77.pem  cert.pem
cert121.pem  cert145.pem  cert30.pem   cert54.pem  cert78.pem
cert122.pem  cert146.pem  cert31.pem   cert55.pem  cert79.pem
cert123.pem  cert147.pem  cert32.pem   cert56.pem  cert7.pem
$

4. OracleウォレットにルートCA証明書を追加する

orapki wallet add -trusted_cert -cert コマンドでOracleウォレットにルートCA証明書を追加します。

$ for i in /var/tmp/cert*.pem ; do
> orapki wallet add -wallet ${ORACLE_WALLET_PATH} -trusted_cert -cert \
>   "$i" -pwd ${ORACLE_WALLET_PWD}
> done
Oracle PKI Tool : Version 11.2.0.3.0 - Production
Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
  :
Oracle PKI Tool : Version 11.2.0.3.0 - Production
Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
$

5. OracleウォレットをOPENして、UTL_HTTPでHTTPSアクセスする

ルートCA証明書を追加したOracleウォレットをOPENしてから、HTTPSのURLにアクセスします。

$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.3.0 Production on 金 12月 11 12:11:11 2015

Copyright (c) 1982, 2011, Oracle.  All rights reserved.



Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
に接続されました。
SQL> define ORACLE_WALLET_PATH=/var/tmp/wallet
SQL> define ORACLE_WALLET_PWD=WalletPasswd123
SQL> define url=https://support.oracle.com
SQL>
SQL> EXEC UTL_HTTP.SET_WALLET('file:&ORACLE_WALLET_PATH', '&ORACLE_WALLET_PWD');

PL/SQLプロシージャが正常に完了しました。

SQL> SELECT UTL_HTTP.REQUEST('&url') FROM DUAL;

旧   1: SELECT UTL_HTTP.REQUEST('&url') FROM DUAL
新   1: SELECT UTL_HTTP.REQUEST('https://support.oracle.com') FROM DUAL

UTL_HTTP.REQUEST('HTTPS://SUPPORT.ORACLE.COM')
--------------------------------------------------------------------------------
<HTML>
<HEAD>
<title>Oracle Configuration Support Manager</title>
<meta http-equiv="REFRESH" content="0;url=/epmos/faces/MosIndex.jspx"></HEAD>
<BODY>
</BODY>
</HTML>

SQL>

HTTPSでアクセスできました。 :-)

参考

About

2015年12月14日 00:20に投稿されたエントリーのページです。

ひとつ前の投稿は「REST APIを用いてOracle Database Cloud Serviceインスタンスを作成する」です。

次の投稿は「Oracle Database 10gの資格がINACTIVE(失効)に」です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。