Lowent 매뉴얼←↑→

verify — 인증서 서명과 체인의 한 마디 확인

소스
lib/verify.low
층
L0 — 순수 계산(호출자의 뒷받침)
권한
없음

x509 가 인증서를 읽어 주면, 이 모듈은 그 위에서 인증서 한 장이 다른 한 장에게 서명받았는가를 답한다. 서명 확인에 더해 유효기간 · 이름 이어짐 · 호스트 이름 대조까지, 체인의 한 마디를 잇는 데 필요한 판단을 한 자리에 모았다.

무엇을 약속하고 무엇을 하지 않나

감사받지 않았다. 받는 서명 알고리즘은 넷뿐이다 — RSA v1.5 + SHA-256 · RSA v1.5 + SHA-384 · ECDSA + SHA-256 · ECDSA + SHA-384. 그 밖(SHA-512 계열 · RSA-PSS 서명 인증서 · Ed25519 인증서 · P-521)을 만나면 거절한다. 폐기 확인도 없다. 모르는 알고리즘을 통과시키면 그때부터 이 모듈의 답은 «확인했다» 가 아니라 «못 알아봤다» 가 되기 때문이다.

체인은 마디의 줄이다#

웹 서버가 보내는 인증서는 보통 세 층이다. 각 층은 바로 위 층에게 서명받고, 맨 위(뿌리)는 우리가 미리 믿기로 한 것이어야 한다.

  뿌리 (신뢰 저장소 안)        ← trust.find_anchor 가 찾는다
     │  서명
     ▼
  중간 인증기관                ← link_ok 중간자 · 뿌리
     │  서명
     ▼
  잎 (example.com)             ← link_ok 잎 · 중간자  +  host_ok 잎 · "example.com"

link_ok 를 아래에서 위로 마디마다 부르고, 잎에는 host_ok 를 더한다. 하나라도 1 이 아니면 체인은 끊긴다. 체인을 어떻게 모으는지(서버가 보낸 순서, 몇 마디까지)는 부르는 쪽이 정한다 — 실제 예는 apps/lowget 이다.

값뜻
1잇는다 — 서명 · CA · 이름 · 기간이 모두 맞다
2자식의 발급자 이름이 부모의 주체 이름과 다르다
3부모가 남을 발급할 수 있는 인증서(CA)가 아니다
4둘 중 하나가 유효기간 밖이다
5서명이 맞지 않는다(또는 모르는 알고리즘)
6서명을 확인할 작업 공간이 모자랐다 — 잰 결과가 아니라 재지 못한 것이다

표 50.1 — link_ok 가 내는 수 — 1 이 아니면 거절한 까닭

op#

op하는 일
link_ok한 마디를 잇는다(위 표). 바이트 작업 공간 1024 · 조각 작업 공간 2200 이상
signed_by자식이 부모에게 서명받았는가 — ok 1 / ok 0, 자리가 모자라면 error short_workspace
sig_kind자식이 적은 서명 알고리즘: 1 RSA+SHA-256 · 2 ECDSA+SHA-256 · 3 RSA+SHA-384 · 4 ECDSA+SHA-384 · 0 모른다
dn_eq두 이름이 바이트로 같은가
dates_ok유효기간이 지금(YYYYMMDDhhmmss 한 수)을 담는가
host_ok · san_matches호스트 이름이 주체 대체 이름 중 하나와 맞는가
ecdsa_rsDER 로 싼 ECDSA 서명에서 r · s 를 곡선 크기(32 · 48 바이트) 자리에 오른쪽 맞춤으로 꺼낸다
curve · curve384P-256 · P-384 의 상수(p · n · Gx · Gy)를 작업 공간에 채운다

표 50.2 — verify 의 op

설계#

서명은 원본 바이트 위에서 확인한다. x509.tbs_off … tbs_end 를 그대로 해시한다. 베낀 자리에서 확인하면 베끼기가 틀려도 서명이 맞아 보일 수 있다.

곡선은 공개키 길이가 가른다. 65 바이트면 P-256(p256), 97 바이트면 P-384(p384). RSA 는 rsa 로 간다.

이름은 바이트로 견준다. DER 은 한 이름에 한 바이트열이므로 그것이 옳다. 문자열로 풀어 견주면 대소문자 · 인코딩 · 공백 규칙이 끼어들고, 그 규칙마다 «같다» 의 뜻이 조금씩 달라진다.

와일드카드는 맨 앞 한 마디만. *.a.b 는 x.a.b 와 맞고 a.b 나 y.x.a.b 와는 맞지 않는다(RFC 6125 §6.4.3). 대소문자는 아스키로만 내린다.

ecdsa_rs 의 오른쪽 맞춤. DER 정수는 앞에 0 이 붙거나(최상위 비트가 1 이면) 짧을 수 있다. 그냥 베끼면 한 바이트 밀린 값으로 검증하게 되고, 그 실수는 언제나 «서명이 틀렸다» 로만 보인다.

모자람은 실패다. 작업 공간이 좁으면 error short_workspace 다 — 예전에는 «자리가 모자람» 과 «서명이 아님» 이 둘 다 0 이어서, 작업 공간을 잘못 준 프로그램이 «서명이 틀렸다» 로 보였다.