Crypt-Bear
view release on metacpan or search on metacpan
src/x509/asn1.t0 view on Meta::CPAN
0x18 = { y4d }
check-primitive
read-length-open-elt
\ We compute the days and seconds counts during decoding, in
\ order to minimize the number of needed temporary variables.
{ ; days seconds x }
\ Year is 4-digit with GeneralizedTime. With UTCTime, the year
\ is in the 1950..2049 range, and only the last two digits are
\ present in the encoding.
read-dec2
y4d if
100 * >x read-dec2 x +
else
dup 50 < if 100 + then 1900 +
then
>x
x 365 * x 3 + 4 / + x 99 + 100 / - x 399 + 400 / + >days
\ Month is 1..12. Number of days in a months depend on the
\ month and on the year (year count is in x at that point).
1 12 read-dec2-range
1- 1 <<
x 4 % 0= x 100 % 0<> x 400 % 0= or and if 24 + then
month-to-days + data-get16
dup 5 >> days + >days
0x1F and
\ Day. At this point, the TOS contains the maximum day count for
\ the current month.
1 swap read-dec2-range
days + 1- >days
\ Hour, minute and seconds. Count of seconds is allowed to go to
\ 60 in case of leap seconds (in practice, leap seconds really
\ occur only at the very end of the day, so this computation is
\ exact for a real leap second, and a spurious leap second only
\ implies a one-second shift that we can ignore).
0 23 read-dec2-range 3600 * >seconds
0 59 read-dec2-range 60 * seconds + >seconds
0 60 read-dec2-range seconds + >seconds
\ At this point, we may have fractional seconds. This should
\ happen only with GeneralizedTime, but we accept it for UTCTime
\ too (and, anyway, we ignore these fractional seconds).
read8 dup `. = if
drop
begin read8 dup `0 `9 between? while drop repeat
then
\ The time zone should be 'Z', not followed by anything. Other
\ time zone indications are not DER and thus not supposed to
\ appear in certificates.
`Z <> if ERR_X509_BAD_TIME fail then
close-elt
days seconds ;
\ Read an INTEGER (tag, length and value). The INTEGER is supposed to be
\ positive; its unsigned big-endian encoding is stored in the provided
\ in-context buffer. Returned value is the decoded length. If the integer
\ did not fit, or the value is negative, then an error is reported.
: read-integer ( lim addr len -- lim dlen )
rot read-tag 0x02 check-tag-primitive -rot
read-integer-next ;
\ Identical to read-integer, but the tag has already been read and checked.
: read-integer-next ( lim addr len -- lim dlen )
dup { addr len origlen }
read-length-open-elt
\ Read first byte; sign bit must be 0.
read8 dup 0x80 >= if ERR_X509_OVERFLOW fail then
\ Skip leading bytes of value 0. If there are only bytes of
\ value 0, then return.
begin dup 0 = while
drop dup ifnot drop 0 ret then
read8
repeat
\ At that point, we have the first non-zero byte on the stack.
begin
len dup ifnot ERR_X509_LIMIT_EXCEEDED fail then 1- >len
addr set8 addr 1+ >addr
dup while read8
repeat
drop origlen len - ;
\ Read a BOOLEAN value. This should be called immediately after reading
\ the tag.
: read-boolean ( lim constructed value -- lim bool )
0x01 check-tag-primitive
read-length 1 <> if ERR_X509_BAD_BOOLEAN fail then
read8 0<> ;
\ Identify an elliptic curve: read the OID, then check it against the
\ known curve OID.
: read-curve-ID ( lim -- lim curve )
read-OID ifnot ERR_X509_UNSUPPORTED fail then
choice
ansix9p256r1 eqOID uf 23 enduf
ansix9p384r1 eqOID uf 24 enduf
ansix9p521r1 eqOID uf 25 enduf
ERR_X509_UNSUPPORTED fail
endchoice ;
\ A convenient debug word: print the current data stack contents.
cc: DEBUG ( -- ) {
extern int printf(const char *fmt, ...);
uint32_t *p;
printf("<stack:");
for (p = &CTX->dp_stack[0]; p != dp; p ++) {
printf(" %lu", (unsigned long)*p);
}
printf(" >\n");
}
( run in 2.470 seconds using v1.01-cache-2.11-cpan-75ffa21a3d4 )