[インデックス 11025] ファイルの概要
このコミットは、Go言語の標準ライブラリであるcrypto/tls
パッケージ内のgenerate_cert.go
ファイルに対する更新です。具体的には、Goのtime
パッケージのAPI変更に対応し、証明書生成スクリプトにおける時刻の取得と期間計算の方法を現代的なAPIに移行しています。
コミット
commit d5e6b8d016774776d3ca6af72839a9138e2fe996
Author: Adam Langley <agl@golang.org>
Date: Wed Jan 4 14:56:16 2012 -0500
crypto/tls: update generate_cert.go for new time package
Fixes #2635.
R=golang-dev, iant
CC=golang-dev
https://golang.org/cl/5512043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/d5e6b8d016774776d3ca6af72839a9138e2fe996
元コミット内容
--- a/src/pkg/crypto/tls/generate_cert.go
+++ b/src/pkg/crypto/tls/generate_cert.go
@@ -31,7 +31,7 @@ func main() {
return
}
- now := time.Seconds()
+ now := time.Now()
template := x509.Certificate{
SerialNumber: new(big.Int).SetInt64(0),
@@ -39,8 +39,8 @@ func main() {
CommonName: *hostName,
Organization: []string{"Acme Co"},
},
- NotBefore: time.SecondsToUTC(now - 300),
- NotAfter: time.SecondsToUTC(now + 60*60*24*365), // valid for 1 year.
+ NotBefore: now.Add(-5 * time.Minute).UTC(),
+ NotAfter: now.AddDate(1, 0, 0).UTC(), // valid for 1 year.
SubjectKeyId: []byte{1, 2, 3, 4},
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
変更の背景
この変更の背景には、Go言語の標準ライブラリにおけるtime
パッケージの進化があります。初期のGoでは、時刻の取得や操作にtime.Seconds()
のような関数が使われることがありましたが、これはfloat64
型で秒数を返すため、型安全性が低く、時間の概念を正確に表現する上で不十分な点がありました。また、期間の計算も秒数を直接加減算する形で行われており、特に年単位のような期間を扱う際にはうるう年などを考慮しない単純な秒数計算では不正確になる可能性がありました。
Go開発チームは、より堅牢で表現力豊かな時刻・期間操作APIを提供するため、time.Time
構造体を中心とした新しいAPIを導入しました。これには、現在の時刻をtime.Time
型で返すtime.Now()
、time.Duration
型を用いた期間の加減算を行うTime.Add()
、そして年・月・日単位での期間加算を正確に行うTime.AddDate()
などが含まれます。
このコミットは、generate_cert.go
という証明書生成スクリプトが、これらの新しいtime
パッケージのAPIに準拠するように更新されたものです。これにより、証明書の有効期間(NotBefore
とNotAfter
)の設定が、より正確かつGoのイディオムに沿った形で行われるようになります。コミットメッセージにあるFixes #2635
は、この変更が特定の課題(おそらく古いtime
パッケージAPIの使用に関する問題や、より新しいAPIへの移行の必要性)を解決したことを示しています。
前提知識の解説
- Go言語の
time
パッケージ: Go言語で時刻と期間を扱うための標準パッケージです。time.Time
: 特定の時点を表す構造体です。ナノ秒単位の精度を持ち、タイムゾーン情報も保持できます。time.Duration
: 期間を表す型です。ナノ秒単位で内部的に表現され、time.Second
やtime.Minute
のような定数を使って直感的に期間を指定できます。time.Now()
: 現在のローカル時刻をtime.Time
型で返します。Time.Add(d Duration)
:Time
にDuration
を加算した新しいTime
を返します。Time.AddDate(years int, months int, days int)
:Time
に指定された年、月、日を加算した新しいTime
を返します。これは、うるう年や各月の異なる日数などを考慮して正確な日付計算を行います。Time.UTC()
:Time
をUTC(協定世界時)に変換した新しいTime
を返します。
crypto/tls
パッケージ: Go言語でTLS(Transport Layer Security)およびSSL(Secure Sockets Layer)プロトコルを実装するためのパッケージです。安全なネットワーク通信を提供します。x509
パッケージ: X.509証明書を解析、生成、検証するためのパッケージです。x509.Certificate
: X.509証明書の構造を表す型です。NotBefore
: 証明書が有効になる開始日時を示すフィールドです。NotAfter
: 証明書が有効でなくなる終了日時を示すフィールドです。
big.Int
: 任意精度の整数を扱うための型です。ここでは証明書のシリアル番号を設定するために使用されています。- UTC (Coordinated Universal Time): 協定世界時。世界の標準時であり、タイムゾーンの影響を受けない普遍的な時刻表現です。証明書の有効期間は通常UTCで指定されます。
技術的詳細
このコミットの核心は、Goのtime
パッケージにおけるAPIのパラダイムシフトを反映したものです。
-
時刻の取得:
- 変更前:
now := time.Seconds()
time.Seconds()
は、Unixエポック(1970年1月1日00:00:00 UTC)からの秒数をfloat64
型で返していました。これは、時刻を数値として扱うため、型安全性が低く、時間の概念を直接的に表現するtime.Time
型に比べて直感的ではありませんでした。
- 変更後:
now := time.Now()
time.Now()
は、現在のローカル時刻をtime.Time
型の値として返します。time.Time
は、年、月、日、時、分、秒、ナノ秒、タイムゾーン情報など、時刻に関する豊富な情報を持つ構造体であり、より正確で型安全な時刻表現を可能にします。
- 変更前:
-
期間の計算とUTC変換:
- 変更前:
NotBefore: time.SecondsToUTC(now - 300)
NotAfter: time.SecondsToUTC(now + 60*60*24*365)
- 古いAPIでは、
now
がfloat64
の秒数であるため、期間の加減算も秒数の直接的な加減算で行われていました(例:now - 300
で5分前、60*60*24*365
で1年)。 time.SecondsToUTC()
は、秒数をUTCのtime.Time
に変換する関数でした。- この方法では、特に1年間の有効期間を計算する際に、うるう年を考慮しないため、厳密には不正確になる可能性がありました。
- 変更後:
NotBefore: now.Add(-5 * time.Minute).UTC()
NotAfter: now.AddDate(1, 0, 0).UTC()
- 新しいAPIでは、
now
がtime.Time
型であるため、そのメソッドを使って期間を操作します。 now.Add(-5 * time.Minute)
:time.Time
型のnow
からtime.Duration
型の-5 * time.Minute
(-5分)を減算し、新しいtime.Time
を生成します。time.Minute
はtime.Duration
型の定数であり、期間の指定が非常に明確になります。now.AddDate(1, 0, 0)
:time.Time
型のnow
に1年、0ヶ月、0日を加算した新しいtime.Time
を生成します。このメソッドは、うるう年などの暦の規則を正確に考慮して日付を計算するため、証明書の有効期間のような厳密な日付計算に適しています。.UTC()
: 最後にUTC()
メソッドを呼び出すことで、計算された時刻を協定世界時(UTC)に変換しています。これは、証明書の有効期間が通常UTCで指定されるという慣習に沿ったものです。
- 変更前:
この変更により、コードの可読性が向上し、時刻と期間の計算がより正確かつ堅牢になりました。
コアとなるコードの変更箇所
src/pkg/crypto/tls/generate_cert.go
ファイルにおいて、以下の3行が変更されています。
- 時刻の現在値取得:
- now := time.Seconds() + now := time.Now()
- 証明書の有効開始日時 (
NotBefore
) の設定:- NotBefore: time.SecondsToUTC(now - 300), + NotBefore: now.Add(-5 * time.Minute).UTC(),
- 証明書の有効終了日時 (
NotAfter
) の設定:- NotAfter: time.SecondsToUTC(now + 60*60*24*365), // valid for 1 year. + NotAfter: now.AddDate(1, 0, 0).UTC(), // valid for 1 year.
コアとなるコードの解説
-
now := time.Now()
:- これは、現在のシステム時刻を
time.Time
型の変数now
に格納する変更です。古いtime.Seconds()
がfloat64
で秒数を返していたのに対し、time.Now()
はGoのtime
パッケージが提供する豊富な機能を持つtime.Time
構造体を返します。これにより、後続の時刻操作がよりオブジェクト指向的かつ安全に行えるようになります。
- これは、現在のシステム時刻を
-
NotBefore: now.Add(-5 * time.Minute).UTC()
:- 証明書の有効開始日時を設定する行です。
- 変更前は、現在の秒数から300秒(5分)を減算し、それをUTCに変換していました。
- 変更後は、
time.Time
型のnow
に対してAdd
メソッドを使用しています。-5 * time.Minute
という表現は、time.Duration
型を利用して「5分前」という期間を明確に示しており、コードの意図が非常に読みやすくなっています。最後に.UTC()
を呼び出すことで、結果の時刻が協定世界時であることを保証しています。
-
NotAfter: now.AddDate(1, 0, 0).UTC()
:- 証明書の有効終了日時を設定する行です。
- 変更前は、現在の秒数に1年分の秒数(
60*60*24*365
)を単純に加算し、それをUTCに変換していました。この方法はうるう年を考慮しないため、厳密な1年後の日付を保証できませんでした。 - 変更後は、
time.Time
型のnow
に対してAddDate
メソッドを使用しています。AddDate(1, 0, 0)
は、now
に1年、0ヶ月、0日を加算することを意味します。このメソッドは、うるう年や各月の異なる日数を自動的に考慮するため、暦上の正確な1年後の日付を計算できます。これにより、証明書の有効期間の計算がより堅牢かつ正確になりました。同様に、最後に.UTC()
を呼び出してUTCに変換しています。
これらの変更は、Goのtime
パッケージが提供する現代的でイディオムに沿ったAPIを活用することで、コードの品質、可読性、そして正確性を向上させています。
関連リンク
- Go言語
time
パッケージのドキュメント: https://pkg.go.dev/time - Go言語
crypto/tls
パッケージのドキュメント: https://pkg.go.dev/crypto/tls - Go言語
crypto/x509
パッケージのドキュメント: https://pkg.go.dev/crypto/x509 - Go言語のIssueトラッカー (一般的な情報): https://go.dev/issue
参考にした情報源リンク
- Web search results for "golang time package changes 2012 time.Seconds time.Now"
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFPUdt3LHNKIzrUlwvcOTaWjF9R_dUBCKzmY2V4Ihwcl2dYBovYUcA0yzT6ryPIplxKpOj1OU9mrgK85QKsFwvtiPsS_MIZUttBEx37CEM4pFNjQjBzl9o006rXoj8EYfqcJcxET_gFcL_UDqE=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEpG03KmwR3O2RIMMBubA9ARQnT5zfncJqYYGXWGDqeZo1RigLbUii9BKQHBl8WuDVfLM1zE57TMojFz5gE4Av-ju-MYmRf1Qyu0qBDlyjXkSXp
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHCbE24TMy-FnrBcXCp-b94HEvt3eFqrc5SiICwCp5AetJovhqLufyOJEQbtGiSgLBZTQ0gAxiOS2xT1TLazHr2SSlVQ3gPmliU5qE5U8U31iWST05IYia-yTqO6tlDIrCvFnuk4y3sdyDxwE64c82
- Web search results for "golang issue 2635" (直接的な関連Issueは見つからなかったが、一般的なGoのIssueトラッカーの参照として)
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHlTeLs9e-5vxvXHoI7bGUqT8L_yggF-hj4ha9vdqglQ-rCs08VOuPAn2U4DNyEKSAptFrm-sskdlL_Mw3qTY3e0tUkfDv3Kojuq_7yyzhJ1ETOACofaeS9L5NyRFHBTQ==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEU4PK0HdOHgIIzfCu4zHgeHjaPlfA_JLOFgj5NT7k5i-3eHGiSLCTtaN0NCTDNLfh79pvZ19ax_PaDI2b30aAr6yvWd7_bBPqxlv9Ks32-8nDvOJ6zKiUS0x0fs9DtVMR9yTjEQb9kl8LcsDzA