Crypt-Bear
view release on metacpan or search on metacpan
src/x509/asn1.t0 view on Meta::CPAN
read8 x dup 0xFFFFFF >= if ERR_X509_OVERFLOW fail then
8 << + >x
repeat
drop x ;
\ Compare the OID in the pad with an OID in the constant data block.
\ Returned value is -1 on equality, 0 otherwise.
cc: eqOID ( addrConst -- bool ) {
const unsigned char *a2 = &t0_datablock[T0_POP()];
const unsigned char *a1 = &CTX->pad[0];
size_t len = a1[0];
int x;
if (len == a2[0]) {
x = -(memcmp(a1 + 1, a2 + 1, len) == 0);
} else {
x = 0;
}
T0_PUSH((uint32_t)x);
}
\ Compare two blobs in the context. Returned value is -1 on equality, 0
\ otherwise.
cc: eqblob ( addr1 addr2 len -- bool ) {
size_t len = T0_POP();
const unsigned char *a2 = (const unsigned char *)CTX + T0_POP();
const unsigned char *a1 = (const unsigned char *)CTX + T0_POP();
T0_PUSHi(-(memcmp(a1, a2, len) == 0));
}
\ Check that a value is in a given range (inclusive).
: between? ( x min max -- bool )
{ min max } dup min >= swap max <= and ;
\ Convert the provided byte value into a number in the 0..9 range,
\ assuming that it is an ASCII digit. A non-digit triggers an error
\ (a "bad time" error since this is used in date/time decoding).
: digit-dec ( char -- value )
`0 - dup 0 9 between? ifnot ERR_X509_BAD_TIME fail then ;
\ Read two ASCII digits and return the value in the 0..99 range. An
\ error is reported if the characters are not ASCII digits.
: read-dec2 ( lim -- lim x )
read8 digit-dec 10 * { x } read8 digit-dec x + ;
\ Read two ASCII digits and check that the value is in the provided
\ range (inclusive).
: read-dec2-range ( lim min max -- lim x )
{ min max }
read-dec2 dup min max between? ifnot ERR_X509_BAD_TIME fail then ;
\ Maximum days in a month and accumulated day count. Each
\ 16-bit value contains the month day count in its lower 5 bits. The first
\ 12 values are for a normal year, the other 12 for a leap year.
data: month-to-days
hexb| 001F 03FC 077F 0B5E 0F1F 12FE 16BF 1A9F 1E7E 223F 261E 29DF |
hexb| 001F 03FD 079F 0B7E 0F3F 131E 16DF 1ABF 1E9E 225F 263E 29FF |
\ Read a date (UTCTime or GeneralizedTime). The date value is converted
\ to a day count and a second count. The day count starts at 0 for
\ January 1st, 0 AD (that's they year before 1 AD, also known as 1 BC)
\ in a proleptic Gregorian calendar (i.e. Gregorian rules are assumed to
\ extend indefinitely in the past). The second count is between 0 and
\ 86400 (inclusive, in case of a leap second).
: read-date ( lim -- lim days seconds )
\ Read tag; must be UTCTime or GeneralizedTime. Year count is
\ 4 digits with GeneralizedTime, 2 digits with UTCTime.
read-tag
dup 0x17 0x18 between? ifnot ERR_X509_BAD_TIME fail then
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
( run in 2.033 seconds using v1.01-cache-2.11-cpan-df04353d9ac )