SVX日記

2004|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|10|11|

2023-09-01(Fri) Maveでデジタル署名付きメールを検証する

  Maveでデジタル署名付きメールを送信できるようになったら、当然、デジタル署名付きメールを受信できるようにもなるべきで、つまりそれは、メールの署名を検証する機能の追加である。

  つうわけで追加してみた。これも、メール本文を丸ごとPKCS7クラスに食わせるだけでできてしまった。後で気づいて、送信者のメールアドレスと証明書内のメールアドレスが一致していることの確認も追加したが。

+   #--------------------------------------------- MaveMail ----
+   #
+   #   メールの署名を検証する
+   #
+   def verify_sign
+       sender = (from =~ /(.*)<(.+)>/ ? $2 : from).strip
+       if(@header['Content-type'] =~ /^multipart\/signed/)
+           begin
+               pkcs7 = OpenSSL::PKCS7.read_smime(File.open(path).read)
+               addrs = []; pkcs7.certificates.each {|cert|
+                   cert.subject.to_a.each {|name|
+                       name[0] == 'emailAddress' and addrs << name[1]
+                   }
+               }
+               if(sender != addrs[0])
+                   yield([_('Digital Signature is NOT Valid. reason=[%s]'), 'Sender does not match Signer.'])
+                   folder.invalid_sign(sq)
+               elsif(pkcs7.verify(nil, @configs[:CERTS_STORE]))
+                   yield([_('Message is Signed.')])
+                   folder.valid_sign(sq)
+               else
+                   yield([_('Digital Signature is NOT Valid. reason=[%s]'), pkcs7.error_string])
+                   folder.invalid_sign(sq)
+               end
+           rescue
+               yield([_('Digital Signature Verify Error. reason=[%s]'), $!.to_s])
+               folder.invalid_sign(sq)
+           end
+       else
+           yield([_('Mail has no signature.')])
+       end
+   end

  画像の説明

  署名を検証はpop時に行うようにし、結果は「@(添付あり)」の表示位置に押し込んだ。「C」なら署名が有効「?」なら無効だ。署名自体が添付ファイルではあるものの、添付ファイル付きの署名付きメールとの識別ができなくなるが、それはまぁよしとする。

  そんなことをやっていると、送信側にバグを見つけた。署名を行う処理に、認証局証明書や中間証明書が必要な場合にそれを含める処理が抜けていた。以下に修正。

        pkcs12 = @account.pkcs12
-       pkcs7 = OpenSSL::PKCS7.sign(pkcs12.certificate, pkcs12.key, data, [], OpenSSL::PKCS7::DETACHED)
+       pkcs7 = OpenSSL::PKCS7.sign(pkcs12.certificate, pkcs12.key, data, pkcs12.ca_certs, OpenSSL::PKCS7::DETACHED)
        smime = OpenSSL::PKCS7.write_smime(pkcs7)               # 署名付きメール(crlf, lf が混じっている)

  そんなこんなで、電子署名(S/MIME)機能の実装はひと通り完了してしまったわけだが、実装しながら別のアイデアを思いついてしまった。テキストベースのメーラなのに、画像の表示ができたら面白いなと。

  解像度がないのでややモザイク状にはなるものの、端末画面に画像を表示する「catimg」というプログラムは既に存在していて、だいぶ前に自ら使いやすいラッパーを作って便利に使っていた。つうか、そのエントリで既にMaveに組み込むアイデアについて記述してあるじゃねぇか。

  そこでcatimgの出力を流用しようとしたがうまくいかない。つうか、そんなことやるよりcatimgのコード読んでスクラッチからRubyで書くべきじゃないか?と、思い直してコードを読む。ほほーん。そういう原理だったのか。

  端末には「文字色」と「背景色」を24bitカラーで指定できるエスケープシーケンスがある。それを使えば「文字単位」でドット表示ができる。しかし、それだと縦長のドットになってしまう。そこで「▀」という「上半分塗りつぶし」文字を使えば「文字色」と「背景色」とで上下を塗り分けることができ、ほぼ正方形のドット表示が可能になる。単純な原理だが、発想がすごいな。実にmz-700っぽく、不可能はないっぽい。

  つうわけで、試験的にコードを書いてみた。

require 'rmagick'
 
png_image = Magick::Image.read('r9.png')
w = png_image[0].columns
h = png_image[0].rows
 
(h >> 1).times {|y|
    w.times {|x|
        cs = []
        c = png_image[0].pixel_color(x, y * 2)
        cs << (c.red >> 8); cs << (c.green >> 8); cs << (c.blue >> 8)
        c = png_image[0].pixel_color(x, y * 2 + 1)
        cs << (c.red >> 8); cs << (c.green >> 8); cs << (c.blue >> 8)
        print("\e[38;2;%d;%d;%dm\e[48;2;%d;%d;%dm\u2580\e[m" % cs)
    }
    puts
}

  画像の説明

  おぉお……我ながら感動的だ。いったんファイルに出力し、catで表示しているのがキモだ。「画面はハメコミ合成ではありません」ぜw。