2014-03-26:curl: (58) unable to set private key file
クライアント証明書を必要とするとある web API を curl 使って叩こうとして、送られてきた p12 ファイルからクライアント証明書を作ったはいいものの、そのクライアント証明書を curl の引数で渡して API 叩こうとしたところでタイトルのエラーが出てはまったというオハナシ。
この手の問題って年1弱な頻度でぶつかってる気がするんだけど、低頻度なだけにいろいろ覚えてなくて、毎度似たような調べ物をして記憶を取り戻してる感じなのよね。
自分の行動の時系列を追っているので、同様の問題にぶち当たって「結論だけ知りたい」方は、さくっとページ送って最後の方を見てください。
まず、.p12 ファイルからクライアント証明書な .pem を作った。
$ openssl pkcs12 -in hoge.p12 -out client.pem
で、これを使って curl で API を叩くんだけど、
$ /usr/bin/curl -E ./client.pem:xxxx -X POST -H 'Content-type: text/xml' -d 'aho ' https://dokkano/api curl: (58) unable to set private key file: ‘./client.pem’ type PEM
あれ? client.pem のパスワード間違ってる?
コマンドラインに入れずに、プロンプトさせて、手動で打ってみても同じ。
$ /usr/bin/curl -E ./client.pem:xxxx -X POST -H 'Content-type: text/xml' -d 'aho ' https://dokkano/api Enter PEM pass phrase: ←ここでパスワードを入力 curl: (58) unable to set private key file: './client.pem' type PEM
おかしいな、ほんとにパスワードが違うんだろうか。。。
-text で中身見れるかの確認をしてみよう。
$ openssl rsa -text -in client.pem Enter pass phrase for client.pem: ←正しいパスワードを入力 Private-Key: (2048 bit) modulus: 00:aa:bb:cc:dd:ff:01:02:03:04:05:06:07:08:09: 12:34:56:78:9a:bc:de:f0:11:22:33:44:55:66:77: .... $ openssl rsa -text -in client.pem Enter pass phrase for client.pem: ←わざと間違ったパスワードを入力 unable to load Private Key 22705:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:325: 22705:error:23077074:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 cipherfinal error:p12_decr.c:97: 22705:error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:pkcs12 pbe crypt error:p12_decr.c:123: 22705:error:0907B00D:PEM routines:PEM_READ_BIO_PRIVATEKEY:ASN1 lib:pem_pkey.c:125:
やっぱり合ってるじゃん。。。
なにがおかしいんだろう、とググって情報探してみたら、curl のメーリングリストのアーカイブ に、「秘密鍵とクライアント証明書とCA証明書をばらばらにしてやったら上手くいったよ!」というのを発見。
これをヒントに .pem を作り直してやってみる。
$ openssl pkcs12 -in hoge.p12 -out client.pem -clcerts $ /usr/bin/curl -E ./client.pem:xxxx -X POST -H 'Content-type: text/xml' -d 'aho ' https://dokkano/apimanuke
うまくいった!
.pem に一緒に入ったCA証明書がイマイチで撥ねられたってことなのかなぁ。
正直、”unable to set private key file” だけじゃ分からないよ!と思う。
クライアント証明書のパスワードが間違ったときと同じエラーメッセージだしね。