factor/extra/asn1/asn1.factor

234 lines
5.6 KiB
Factor
Raw Normal View History

2007-09-20 18:09:08 -04:00
! Copyright (C) 2007 Elie CHAFTARI
! See http://factorcode.org/license.txt for BSD license.
USING: arrays asn1.ldap assocs byte-arrays combinators
continuations io io.binary io.streams.string kernel math
2008-09-10 23:11:40 -04:00
math.parser namespaces make pack strings sequences accessors ;
2007-09-20 18:09:08 -04:00
IN: asn1
2009-01-19 23:24:30 -05:00
<PRIVATE
: (>128-ber) ( n -- )
dup 0 > [
2011-11-23 21:49:33 -05:00
[ 0x7f bitand 0x80 bitor , ] keep -7 shift
2009-01-19 23:24:30 -05:00
(>128-ber)
] [
drop
] if ;
PRIVATE>
: >128-ber ( n -- str )
[
2011-11-23 21:49:33 -05:00
[ 0x7f bitand , ] keep -7 shift
2009-01-19 23:24:30 -05:00
(>128-ber)
] { } make reverse ;
2007-09-20 18:09:08 -04:00
: tag-classes ( -- seq )
{ "universal" "application" "context_specific" "private" } ;
: builtin-syntax ( -- hashtable )
H{
{ "universal"
H{
{ "primitive"
H{
2007-09-20 18:09:08 -04:00
{ 1 "boolean" }
{ 2 "integer" }
{ 4 "string" }
{ 5 "null" }
{ 6 "oid" }
{ 10 "integer" }
{ 13 "string" } ! relative OID
}
}
{ "constructed"
H{
{ 16 "array" }
{ 17 "array" }
}
}
}
}
{ "context_specific"
H{
{ "primitive"
H{
{ 10 "integer" }
}
}
}
}
} ;
SYMBOL: elements
TUPLE: element syntax id tag tagclass encoding contentlength newobj objtype ;
: get-id ( -- id )
2008-08-30 21:38:07 -04:00
elements get id>> ;
2007-09-20 18:09:08 -04:00
2013-03-29 12:45:06 -04:00
ERROR: unsupported-tag-encoding id ;
2007-09-20 18:09:08 -04:00
: (set-tag) ( -- )
2008-08-30 21:38:07 -04:00
elements get id>> 31 bitand
dup elements get tag<<
2007-09-20 18:09:08 -04:00
31 < [
get-id unsupported-tag-encoding
2007-09-20 18:09:08 -04:00
] unless ;
: set-tagclass ( -- )
get-id -6 shift tag-classes nth
elements get tagclass<< ;
2007-09-20 18:09:08 -04:00
: set-encoding ( -- )
2011-11-23 21:49:33 -05:00
get-id 0x20 bitand
2007-09-20 18:09:08 -04:00
zero? "primitive" "constructed" ?
elements get encoding<< ;
2007-09-20 18:09:08 -04:00
: set-content-length ( -- )
read1
dup 127 <= [
2007-09-20 18:09:08 -04:00
127 bitand read be>
] unless elements get contentlength<< ;
2007-09-20 18:09:08 -04:00
: set-newobj ( -- )
2008-08-30 21:38:07 -04:00
elements get contentlength>> read
elements get newobj<< ;
2007-09-20 18:09:08 -04:00
: set-objtype ( syntax -- )
builtin-syntax 2array [
elements get tagclass>> of
elements get encoding>> of
2008-08-30 21:38:07 -04:00
elements get tag>>
of [
elements get objtype<<
2007-09-20 18:09:08 -04:00
] when*
] each ;
DEFER: read-ber
SYMBOL: end
2008-05-05 05:32:01 -04:00
: (read-array) ( -- )
2008-08-30 21:38:07 -04:00
elements get id>> [
2008-08-31 03:51:31 -04:00
elements get syntax>> read-ber
2007-09-20 18:09:08 -04:00
dup end = [ drop ] [ , (read-array) ] if
] when ;
: read-array ( -- array ) [ (read-array) ] { } make ;
2008-05-05 05:32:01 -04:00
: set-case ( -- object )
2008-08-31 03:51:31 -04:00
elements get newobj>>
elements get objtype>> {
2007-09-20 18:09:08 -04:00
{ "boolean" [ "\0" = not ] }
{ "string" [ "" or ] }
{ "integer" [ be> ] }
{ "array" [ "" or [ read-array ] with-string-reader ] }
2007-09-20 18:09:08 -04:00
} case ;
2008-08-30 21:38:07 -04:00
: set-id ( -- boolean )
read1 dup elements get id<< ;
2008-08-30 21:38:07 -04:00
2007-09-20 18:09:08 -04:00
: read-ber ( syntax -- object )
2008-08-30 21:38:07 -04:00
element new
swap >>syntax
elements set
2007-09-20 18:09:08 -04:00
set-id [
(set-tag)
set-tagclass
set-encoding
set-content-length
set-newobj
2008-08-31 03:51:31 -04:00
elements get syntax>> set-objtype
2007-09-20 18:09:08 -04:00
set-case
] [ end ] if ;
! =========================================================
! Fixnum
! =========================================================
GENERIC: >ber ( obj -- byte-array )
M: fixnum >ber ( n -- byte-array )
>128-ber dup length 2 swap 2array
"cc" pack-native B{ } prepend-as ;
2007-09-20 18:09:08 -04:00
: >ber-enumerated ( n -- byte-array )
>128-ber dup length 10 swap 2array
"CC" pack-native B{ } prepend-as ;
2007-09-20 18:09:08 -04:00
: >ber-length-encoding ( n -- byte-array )
dup 127 <= [
1array "C" pack-be
] [
1array "I" pack-be 0 swap remove dup length
0x80 + 1array "C" pack-be B{ } prepend-as
2007-09-20 18:09:08 -04:00
] if ;
! =========================================================
! Bignum
! =========================================================
M: bignum >ber ( n -- byte-array )
>128-ber dup length
2007-09-20 18:09:08 -04:00
dup 126 > [
"range error in bignum" throw
] [
2 swap 2array "CC" pack-native B{ } prepend-as
2007-09-20 18:09:08 -04:00
] if ;
! =========================================================
! String
! =========================================================
! Universal octet-string has tag number 4, we should however
! still be able to assign an arbitrary code number.
! >ber words should be called within a with-ber.
SYMBOL: tagnum
TUPLE: tag value ;
: <tag> ( -- <tag> ) 4 tag boa ;
2007-09-20 18:09:08 -04:00
: with-ber ( quot -- )
2012-07-19 16:55:34 -04:00
[ <tag> tagnum ] dip with-variable ; inline
2007-09-20 18:09:08 -04:00
: set-tag ( value -- )
tagnum get value<< ;
2007-09-20 18:09:08 -04:00
M: string >ber ( str -- byte-array )
2008-09-02 13:36:35 -04:00
tagnum get value>> 1array "C" pack-native swap dup
2007-09-20 18:09:08 -04:00
length >ber-length-encoding swapd append swap
>byte-array append ;
: >ber-application-string ( n str -- byte-array )
2011-11-23 21:49:33 -05:00
[ 0x40 + set-tag ] dip >ber ;
2007-09-20 18:09:08 -04:00
: >ber-contextspecific-string ( n str -- byte-array )
2011-11-23 21:49:33 -05:00
[ 0x80 + set-tag ] dip >ber ;
2007-09-20 18:09:08 -04:00
! =========================================================
! Array
! =========================================================
: >ber-seq-internal ( array code -- byte-array )
1array "C" pack-native swap dup length >ber-length-encoding
2013-04-06 20:02:22 -04:00
swapd append swap [ number>string ] map { } concat-as append ;
2007-09-20 18:09:08 -04:00
M: array >ber ( array -- byte-array )
2011-11-23 21:49:33 -05:00
0x30 >ber-seq-internal ;
2007-09-20 18:09:08 -04:00
: >ber-set ( array -- byte-array )
2011-11-23 21:49:33 -05:00
0x31 >ber-seq-internal ;
2007-09-20 18:09:08 -04:00
: >ber-sequence ( array -- byte-array )
2011-11-23 21:49:33 -05:00
0x30 >ber-seq-internal ;
2007-09-20 18:09:08 -04:00
: >ber-appsequence ( array -- byte-array )
2011-11-23 21:49:33 -05:00
0x60 >ber-seq-internal ;
2007-09-20 18:09:08 -04:00
: >ber-contextspecific-array ( array -- byte-array )
2011-11-23 21:49:33 -05:00
0xA0 >ber-seq-internal ;