2010/04/23

ocaml open as

Python やら Haskell だと
import XXXX as Y
みたいなことできますので
OCaml だったらどうするんじゃらほいと思いました

ググったんだけど良く分からず
id:camlspotter さんに聴いちゃいました
答は
module Y = XXXX
でした
なるほど!

というわけで少し試してみることに
$ rlwrap ocaml 
Objective Caml version 3.11.2

# #load "unix.cma";;
# module U = Unix;;
module U :
sig
type error =
Unix.error =
E2BIG
| EACCES
| EAGAIN
| EBADF
| EBUSY
(略)
val setsid : unit -> int
end
# U.connect;;
- : U.file_descr -> U.sockaddr -> unit = <fun>
#
おぉ〜、できてる

gnutls python

悪ノリも大概にしなさいという気がしないでもないですが
どうせならと思って gnutls も使ってみようと
Python であれば python-gnutls というのがあります
easy_install でも pip でも使えば入ってしまいます

example とかも揃っているので良く分かってなくても使えてしまいましたが
from gnutls import crypto

x509 = crypto.X509Certificate(open("google.crt").read())

print "version: %d" % x509.version
print "serial number: %s" % x509.serial_number
print "issuer: %s" % x509.issuer.title()
print "not before: %s" % time.ctime(x509.activation_time)
print "not after: %s" % time.ctime(x509.expiration_time)
print "subject: %s" % x509.subject.title()
とか
import socket
import time

from gnutls import connection

cred = connection.X509Credentials()

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
session = connection.ClientSession(sock, cred)

session.connect(('www.google.com', 443))
session.handshake()
x509 = session.peer_certificate
session.bye()
session.close()

print "version: %d" % x509.version
print "serial number: %s" % x509.serial_number
print "issuer: %s" % x509.issuer.title()
print "not before: %s" % time.ctime(x509.activation_time)
print "not after: %s" % time.ctime(x509.expiration_time)
print "subject: %s" % x509.subject.title()
とかすると
version: 3
serial number: 205024093581220934167709006090448199471
issuer: C=Za,O=Thawte Consulting (Pty) Ltd.,Cn=Thawte Sgc Ca
not before: Fri Dec 18 09:00:00 2009
not after: Mon Dec 19 08:59:59 2011
subject: C=Us,St=California,L=Mountain View,O=Google Inc,Cn=Www.Google.Com
こんなのが出ました

gnutls.constants.X509_FMT_DER とかあるので DER も読めたり
gnutls.library.functions ってのがあるんでガリガリ書いたり
できるのかな? 試していません

とりあえず証明書は読めました

2010/04/21

scala cast

Jython でできたら Scala でもできるべ JK、と思ったら失敗しやんの
というお話

同じようにしようと思ったんですね、Scala で
scala> import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.SSLSocketFactory

scala> val fc = SSLSocketFactory.getDefault
fc: javax.net.SocketFactory = com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl@10c6406

scala> val sock = fc.createSocket("www.google.com", 443)
sock: java.net.Socket = 17aa961[SSL_NULL_WITH_NULL_NULL: Socket[addr=www.google.com/66.249.89.99,port=443,localport=57185]]

scala> sock.startHandshake
<console>:8: error: value startHandshake is not a member of java.net.Socket
sock.startHandshake
^

scala>
java.net.Socket には startHandshake なんて無いと

あれー、と思って調べてみたら
Java の場合は Socket 作るときにキャストしてたんです
なんで調べてみましたところ
型キャスト - うなの日記
.asInstanceOf でキャストするらしい

とわけで仕切り直し
scala> import javax.net.ssl.SSLSocket                                 
import javax.net.ssl.SSLSocket

scala> val ssl_sock = fc.createSocket("www.google.com", 443).asInstanceOf[javax.net.ssl.SSLSocket]
ssl_sock: javax.net.ssl.SSLSocket = 5b55a9[SSL_NULL_WITH_NULL_NULL: Socket[addr=www.google.com/66.249.89.104,port=443,localport=51395]]

scala> ssl_sock.startHandshake

scala> val session = ssl_sock.getSession
session: javax.net.ssl.SSLSession = [Session-1, SSL_RSA_WITH_RC4_128_SHA]

scala> session.getPeerCertificates
res3: Array[java.security.cert.Certificate] =
Array([
[
Version: V3
Subject: CN=www.google.com, O=Google Inc, L=Mountain View, ST=California, C=US
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

Key: Sun RSA public key, 1024 bits
modulus: 16360039926653679142684174795487342200966220249542631283272411000230225514996552443305086682233800494025854567816692732625...
scala>
取れた!!

Scala の方が Java に対して素直なんですかね
何故 Jython でキャストが不要なのか良く分からず
どのくらい手を加えているのかっつーことなんでしょうか

2010/04/20

sslsocketfactory session getdefault

Jython で Java を使って SSL 張って証明書を取ろうとしました

色々ググったりして SSLSocketFactory ってのがあるということで
java.net パッケージの仕組み
を見てふんふんとする
で、socket を作って getSession したらそこに getPeerCertificates という method が!
In [63]: soc = factory.createSocket('www.google.com', 443)

In [1]: from javax.net.ssl import *

In [2]: sock = factory.createSocket('www.google.com', 443)

In [3]: session = sock.getSession()

In [4]: certs = session.getPeerCertificates()
---------------------------------------------------------------------------
SSLPeerUnverifiedException Traceback (most recent call last)

/tmp/<ipython console> in <module>()

SSLPeerUnverifiedException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

In [5]:
うぎゃぁ!!

何か足りないのみたいなのでググり直すと
HTTPS通信にはまる - TNET日々のメモ
そうですよね、handshake してませんでした

ということで
import sys
from javax.net.ssl import SSLSocketFactory

host = "www.google.com"
port = 443

factory = SSLSocketFactory.getDefault()
sock = factory.createSocket(host, port)
sock.startHandshake()
session = sock.getSession()
certs = session.getPeerCertificates()

for c in certs:
print '-----BEGIN CERTIFICATE-----'
print c.getEncoded().tostring().encode('base64').rstrip()
print '-----END CERTIFICATE-----'
Certificate を PEM で出したかったんですが
DER を array で取り出す方法しか分からなかったので
Jython str にして encode してしまいました
てゆーか array なんてあったんだー使ったことないよー

でどうなるかというと
$ jython get_certs.jy www.google.com
-----BEGIN CERTIFICATE-----
MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBMMQswCQYDVQQG
EwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMNVGhh
d3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0xMTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVT
MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApH
b29nbGUgSW5jMRcwFQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jNgtXj9xVo
RaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L05vuuWciKh0R73mkszeK
9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAMBgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0w
K6ApoCeGJWh0dHA6Ly9jcmwudGhhd3RlLmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYI
KwYBBQUHAwEGCCsGAQUFBwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzAB
hhZodHRwOi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0ZS5j
b20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUFAAOBgQCfQ89bxFAp
sb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5u2ONgJd8IyAPkU0Wueru9G2Jysa9
zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqA
ibAxWEEHXw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDIzCCAoygAwIBAgIEMAAAAjANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJVUzEXMBUGA1UE
ChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlm
aWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNTEzMDAwMDAwWhcNMTQwNTEyMjM1OTU5WjBMMQswCQYD
VQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMN
VGhhd3RlIFNHQyBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1NNn0I0Vf67NMf59HZGh
PwtxPKzMyGT7Y/wySweUvW+Aui/hBJPAM/wJMyPpC3QrccQDxtLN4i/1CWPN/0ilAL/g5/OIty0y
3pg25gqtAHvEZEo7hHUD8nCSfQ5i9SGraTaEMXWQ+L/HbIgbBpV8yeWo3nWhLHpo39XKHIdYYBkC
AwEAAaOB/jCB+zASBgNVHRMBAf8ECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjARBglghkgBhvhCAQEE
BAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFByaXZhdGVMYWJlbDMtMTUwMQYDVR0fBCow
KDAmoCSgIoYgaHR0cDovL2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwMgYIKwYBBQUHAQEEJjAk
MCIGCCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDQGA1UdJQQtMCsGCCsGAQUFBwMB
BggrBgEFBQcDAgYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEBBQUAA4GBAFWsY+re
od3SkF+fC852vhNRj5PZBSvIG3dLrWlQoe7e3P3bB+noOZTcq3J5Lwa/q4FwxKjt6lM07e8eU9kG
x1Yr0Vz00YqOtCuxN5BICEIlxT6Ky3/rbwTRbcV0oveifHtgPHfNDs5IAn8BL7abN+AqKjbc1YXW
rOU/VG+WHgWv
-----END CERTIFICATE-----
$
ありゃ、1行が76文字に...

まぁいいや、Java で証明書が取れました

InputStream 文字列

色々ググっていたら
Java(TM) PKI API プログラマーズガイド
ってのを見付けました
こりゃいいや、これに違いない

で、先ず証明書読みたいと思いまして読み進めると
java.security.cert.CertificateFactory
を使うと良いらしく、サンプルも
Java 暗号化アーキテクチャー (JCA)
に書いてありました
FileInputStream fis = new FileInputStream(filename);
BufferedInputStream bis = new BufferedInputStream(fis);

CertificateFactory cf = CertificateFactory.getInstance("X.509");

while (bis.available() > 0) {
Certificate cert = cf.generateCertificate(bis);
System.out.println(cert.toString());
}


でも file を Java で読みたくないなぁ
でも Jython で file 開いた後どうするんだろう
中身を str にしたら何とかならないかな
つわけでググってみると
String文字列をInputStreamに変換する方法 - Java入門
そうそう、こういうの

というわけで簡単に証明書の中身を出してみました
from java.security.cert import CertificateFactory
from java.io import ByteArrayInputStream

pem_file = open("google.pem", "r")
cf = CertificateFactory.getInstance("X.509")
pem_stream = ByteArrayInputStream(pem_file.read())
x509 = cf.generateCertificate(pem_stream)

print x509.version
print x509.sigAlgName
print x509.issuerDN
print x509.notBefore
print x509.notAfter
print x509.subjectDN
これがこうなります
$ jython read_cert.jy
3
SHA1withRSA
CN=Thawte SGC CA, O=Thawte Consulting (Pty) Ltd., C=ZA
Fri Dec 18 09:00:00 JST 2009
Mon Dec 19 08:59:59 JST 2011
CN=www.google.com, O=Google Inc, L=Mountain View, ST=California, C=US
$

Python で開いた file をそのまま InputStream? にする方法もある気がする
今度調べよう

2010/04/18

java http socket

Jython っつっても Java を触りたく
Java のことなんて何も分かってないのを思いだしました
こまった

でもグーグルがあるじゃないか!
インターネット世代だし先ずは 80 番ポートじゃないか!!
教えてグーグル先生!!!

先生優しいので何でも教えてくれます
Java で HTTP クライアントを作ってみよう (1)
Java 関連はグーグル先生特に詳しいみたいでいくらでも出てきます
Java を使うことによるメリットの1つはグーグル先生が詳しいからかっ

で、これを Jython に写経です
import java.net as net
import java.io as io

host = "www.google.com"
port = 80
path = "/"

sock = net.Socket(host, port)
reader = io.BufferedReader(io.InputStreamReader(sock.getInputStream()))
writer = io.BufferedWriter(io.OutputStreamWriter(sock.getOutputStream()))

writer.write("GET %s HTTP/1.0\n\n" % (path,))
writer.flush()

while True:
line = reader.readLine()
if line:
print line
else:
break
で、実行
$ jython get_google.jy
HTTP/1.0 302 Found
Location: http://www.google.co.jp/
Cache-Control: private
Content-Type: text/html; charset=UTF-8
(後略)
動いてしまいました、あっさり

これは、既にどこかに Java -> Jython translator があるに違いない

jython ipython

OpenSSL ばっかりでは飽きてきたし
GNU TLS とかでもいいんだけど
Java のライブラリとか素敵なんじゃないのかしら
でも Java を今からって、private? public? static??

そこで Scala か Clojure かと思ったんですが Jython があるじゃないですか
先ずは Jython から初めようと思いダウンロードしてインストールしてみました
$ time /usr/local/jython-2.5.1/bin/jython /dev/null

real 0m2.870s
user 0m2.844s
sys 0m0.124s
立ち上がりは遅い。このパソコンが重いのか?
未だに EUC-JP 環境にいるので LANG=C とか ja_JP.UTF-8 とかしないと
string なリテラル打ったが最後帰ってこなくなったりしました

さて、Python だったら IPython とかで happy になってるわけなので
補完とかがある Jython が欲しいと思ってとりあえずググると、あるある
How to use IPython with Jython
作業日誌/2010-03-04 - Go's WikiLog

最初書いてある通りにしてるつもりができてなかったので動かず
読み直してちゃんと動きました
$ jython
Python 2.5.1 (Release_2_5_1:6813, Sep 26 2009, 13:47:54)
Type "copyright", "credits" or "license" for more information.

IPython 0.9.1 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.

In [1]: import java

In [2]: java.
java.__name__ java.awt java.io java.math java.nio java.security java.text
java.applet java.beans java.lang java.net java.rmi java.sql java.util

In [2]: java.
Tab で補完もできました
さて、何して遊ぼう