Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Havar
asn1c
Commits
99006369
Commit
99006369
authored
Aug 07, 2004
by
Lev Walkin
Browse files
improved asn_GT2time() and added asn_time2GT() function
parent
0aca3855
Changes
4
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
99006369
...
...
@@ -3,6 +3,7 @@
* Fixed application-level problem in SET OF/SEQUENCE OF array cleanup.
(Severity: medium, Security impact: low)
* Improved asn_GT2time() and added asn_time2{GT,UT}() functions.
0.8.15: 2004-Jul-20
...
...
skeletons/GeneralizedTime.c
View file @
99006369
...
...
@@ -21,7 +21,7 @@ asn1_TYPE_descriptor_t asn1_DEF_GeneralizedTime = {
"GeneralizedTime"
,
GeneralizedTime_constraint
,
/* Check validity of time */
OCTET_STRING_decode_ber
,
/* Implemented in terms of OCTET STRING */
OCTET_STRING
_encode_der
,
/* Implemented in terms of OCTET STRING */
GeneralizedTime
_encode_der
,
/* Implemented in terms of OCTET STRING */
GeneralizedTime_print
,
OCTET_STRING_free
,
0
,
/* Use generic outmost tag fetcher */
...
...
@@ -45,7 +45,7 @@ GeneralizedTime_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
time_t
tloc
;
errno
=
EPERM
;
/* Just an unlikely error code */
tloc
=
asn_GT2time
(
st
,
0
);
tloc
=
asn_GT2time
(
st
,
0
,
0
);
if
(
tloc
==
-
1
&&
errno
!=
EPERM
)
{
_ASN_ERRLOG
(
"%s: Invalid time format: %s"
,
td
->
name
,
strerror
(
errno
));
...
...
@@ -55,6 +55,47 @@ GeneralizedTime_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
return
0
;
}
der_enc_rval_t
GeneralizedTime_encode_der
(
asn1_TYPE_descriptor_t
*
td
,
void
*
ptr
,
int
tag_mode
,
ber_tlv_tag_t
tag
,
asn_app_consume_bytes_f
*
cb
,
void
*
app_key
)
{
GeneralizedTime_t
*
st
=
ptr
;
der_enc_rval_t
erval
;
/* If not canonical DER, re-encode into canonical DER. */
if
(
st
->
size
&&
st
->
buf
[
st
->
size
-
1
]
!=
'Z'
)
{
struct
tm
tm
;
time_t
tloc
;
errno
=
EPERM
;
tloc
=
asn_GT2time
(
st
,
&
tm
,
1
);
/* Recognize time */
if
(
tloc
==
-
1
&&
errno
!=
EPERM
)
{
/* Failed to recognize time. Fail completely. */
erval
.
encoded
=
-
1
;
erval
.
failed_type
=
td
;
erval
.
structure_ptr
=
ptr
;
return
erval
;
}
st
=
asn_time2GT
(
0
,
&
tm
,
1
);
/* Save time canonically */
if
(
!
st
)
{
/* Memory allocation failure. */
erval
.
encoded
=
-
1
;
erval
.
failed_type
=
td
;
erval
.
structure_ptr
=
ptr
;
return
erval
;
}
}
erval
=
OCTET_STRING_encode_der
(
td
,
st
,
tag_mode
,
tag
,
cb
,
app_key
);
if
(
st
!=
ptr
)
{
FREEMEM
(
st
->
buf
);
FREEMEM
(
st
);
}
return
erval
;
}
int
GeneralizedTime_print
(
asn1_TYPE_descriptor_t
*
td
,
const
void
*
sptr
,
int
ilevel
,
asn_app_consume_bytes_f
*
cb
,
void
*
app_key
)
{
...
...
@@ -69,11 +110,11 @@ GeneralizedTime_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
int
ret
;
errno
=
EPERM
;
if
(
asn_GT2time
(
st
,
&
tm
)
==
-
1
&&
errno
!=
EPERM
)
if
(
asn_GT2time
(
st
,
&
tm
,
1
)
==
-
1
&&
errno
!=
EPERM
)
return
cb
(
"<bad-value>"
,
11
,
app_key
);
ret
=
snprintf
(
buf
,
sizeof
(
buf
),
"%04d-%02d-%02d %02d:%02d%02d"
,
"%04d-%02d-%02d %02d:%02d%02d
(GMT)
"
,
tm
.
tm_year
+
1900
,
tm
.
tm_mon
+
1
,
tm
.
tm_mday
,
tm
.
tm_hour
,
tm
.
tm_min
,
tm
.
tm_sec
);
assert
(
ret
>
0
&&
ret
<
(
int
)
sizeof
(
buf
));
...
...
@@ -96,19 +137,19 @@ GeneralizedTime_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
* Where to look for offset from GMT, Phase II.
*/
#ifdef HAVE_TM_ZONE
#define GMTOFF (tm
_s
.tm_gmtoff)
#define GMTOFF
(tm)
(
(tm
)
.tm_gmtoff)
#else
/* HAVE_TM_ZONE */
#define GMTOFF (-timezone)
#define GMTOFF
(tm)
(-timezone)
#endif
/* HAVE_TM_ZONE */
time_t
asn_GT2time
(
const
GeneralizedTime_t
*
st
,
struct
tm
*
_tm
)
{
asn_GT2time
(
const
GeneralizedTime_t
*
st
,
struct
tm
*
ret_tm
,
int
as_gmt
)
{
struct
tm
tm_s
;
uint8_t
*
buf
;
uint8_t
*
end
;
int
tm_
gmtoff_h
=
0
;
int
tm_
gmtoff_m
=
0
;
int
tm_
gmtoff
=
0
;
/* h + m */
int
gmtoff_h
=
0
;
int
gmtoff_m
=
0
;
int
gmtoff
=
0
;
/* h + m */
int
offset_specified
=
0
;
time_t
tloc
;
...
...
@@ -240,22 +281,22 @@ offset:
return
-
1
;
}
buf
++
;
B2F
(
tm_
gmtoff_h
);
B2F
(
tm_
gmtoff_h
);
B2F
(
gmtoff_h
);
B2F
(
gmtoff_h
);
if
(
buf
[
-
3
]
==
0x2D
)
/* Negative */
tm_
gmtoff
=
-
1
;
gmtoff
=
-
1
;
else
tm_
gmtoff
=
1
;
gmtoff
=
1
;
if
((
end
-
buf
)
==
2
)
{
B2F
(
tm_
gmtoff_m
);
B2F
(
tm_
gmtoff_m
);
B2F
(
gmtoff_m
);
B2F
(
gmtoff_m
);
}
else
if
(
end
!=
buf
)
{
errno
=
EINVAL
;
return
-
1
;
}
tm_
gmtoff
=
tm_
gmtoff
*
(
3600
*
tm_
gmtoff_h
+
60
*
tm_
gmtoff_m
);
gmtoff
=
gmtoff
*
(
3600
*
gmtoff_h
+
60
*
gmtoff_m
);
/* Fall through */
utc_finish:
...
...
@@ -282,25 +323,110 @@ local_finish:
tm_s
.
tm_year
-=
1900
;
tm_s
.
tm_isdst
=
-
1
;
tloc
=
mktime
(
&
tm_s
);
tm_s
.
tm_sec
-=
gmtoff
;
/*** AT THIS POINT tm_s is either GMT or local (unknown) ****/
if
(
offset_specified
)
tloc
=
timegm
(
&
tm_s
);
else
{
/*
* Without an offset (or 'Z'),
* we can only guess that it is a local zone.
* Interpret it in this fashion.
*/
tloc
=
mktime
(
&
tm_s
);
}
if
(
tloc
==
-
1
)
{
errno
=
EINVAL
;
return
-
1
;
}
if
(
offset_specified
)
{
/*
* Offset from GMT is specified in the time expression.
*/
tloc
+=
GMTOFF
-
tm_gmtoff
;
if
(
_tm
&&
(
localtime_r
(
&
tloc
,
&
tm_s
)
==
NULL
))
{
/* Could not reconstruct the time */
return
-
1
;
if
(
ret_tm
)
{
if
(
as_gmt
)
{
if
(
offset_specified
)
{
*
ret_tm
=
tm_s
;
}
else
{
if
(
gmtime_r
(
&
tloc
,
ret_tm
)
==
0
)
{
errno
=
EINVAL
;
return
-
1
;
}
}
}
else
{
if
(
localtime_r
(
&
tloc
,
ret_tm
)
==
0
)
{
errno
=
EINVAL
;
return
-
1
;
}
}
}
if
(
_tm
)
memcpy
(
_tm
,
&
tm_s
,
sizeof
(
struct
tm
));
return
tloc
;
}
GeneralizedTime_t
*
asn_time2GT
(
GeneralizedTime_t
*
opt_gt
,
const
struct
tm
*
tm
,
int
force_gmt
)
{
struct
tm
tm_s
;
long
gmtoff
;
const
unsigned
int
buf_size
=
24
;
/* 4+2+2 +2+2+2 +4 + cushion */
char
*
buf
;
char
*
p
;
int
size
;
/* Check arguments */
if
(
!
tm
)
{
errno
=
EINVAL
;
return
0
;
}
/* Pre-allocate a buffer of sufficient yet small length */
buf
=
MALLOC
(
buf_size
);
if
(
!
buf
)
return
0
;
gmtoff
=
GMTOFF
(
*
tm
);
if
(
force_gmt
&&
gmtoff
)
{
tm_s
=
*
tm
;
tm_s
.
tm_sec
-=
gmtoff
;
timegm
(
&
tm_s
);
/* Fix the time */
assert
(
!
GMTOFF
(
tm_s
));
tm
=
&
tm_s
;
}
size
=
snprintf
(
buf
,
buf_size
,
"%04d%02d%02d%02d%02d%02d"
,
tm
->
tm_year
+
1900
,
tm
->
tm_mon
+
1
,
tm
->
tm_mday
,
tm
->
tm_hour
,
tm
->
tm_min
,
tm
->
tm_sec
);
assert
(
size
==
14
);
p
=
buf
+
size
;
if
(
force_gmt
)
{
*
p
++
=
0x5a
;
/* 'Z' */
*
p
++
=
0
;
size
++
;
}
else
{
int
ret
=
snprintf
(
p
,
buf_size
-
size
,
"%+03ld%02ld"
,
gmtoff
/
3600
,
gmtoff
%
3600
);
assert
(
ret
>=
5
&&
ret
<=
7
);
size
+=
ret
;
}
if
(
opt_gt
)
{
if
(
opt_gt
->
buf
)
FREEMEM
(
opt_gt
->
buf
);
}
else
{
opt_gt
=
CALLOC
(
1
,
sizeof
*
opt_gt
);
if
(
!
opt_gt
)
{
free
(
buf
);
return
0
;
}
}
opt_gt
->
buf
=
buf
;
opt_gt
->
size
=
size
;
return
opt_gt
;
}
skeletons/GeneralizedTime.h
View file @
99006369
...
...
@@ -13,14 +13,33 @@ typedef OCTET_STRING_t GeneralizedTime_t; /* Implemented using OCTET STRING */
extern
asn1_TYPE_descriptor_t
asn1_DEF_GeneralizedTime
;
asn_constr_check_f
GeneralizedTime_constraint
;
der_type_encoder_f
GeneralizedTime_encode_der
;
asn_struct_print_f
GeneralizedTime_print
;
/***********************
* Some handy helpers. *
***********************/
/* On error returns -1 and errno set to EINVAL */
struct
tm
;
/* <time.h> */
time_t
asn_GT2time
(
const
GeneralizedTime_t
*
,
struct
tm
*
_optional_tm4fill
);
/*
* Convert a GeneralizedTime structure into time_t
* and optionally into struct tm.
* If as_gmt is given, the resulting _optional_tm4fill will have a GMT zone,
* instead of default local one.
* On error returns -1 and errno set to EINVAL
*/
time_t
asn_GT2time
(
const
GeneralizedTime_t
*
,
struct
tm
*
_optional_tm4fill
,
int
as_gmt
);
/*
* Convert a struct tm into GeneralizedTime.
* If __opt_gt is not given, this function will try to allocate one.
* If force_gmt is given, the resulting GeneralizedTime will be forced
* into a GMT time zone (encoding ends with 'Z').
* On error, this function returns 0 and sets errno.
*/
GeneralizedTime_t
*
asn_time2GT
(
GeneralizedTime_t
*
__opt_gt
,
const
struct
tm
*
,
int
force_gmt
);
#endif
/* _GeneralizedTime_H_ */
skeletons/tests/check-GeneralizedTime.c
View file @
99006369
...
...
@@ -3,7 +3,7 @@
#include "../constraints.c"
static
void
check
(
char
*
time_str
,
time_t
sample
)
{
check
(
char
*
time_str
,
time_t
expect
,
int
as_gmt
)
{
GeneralizedTime_t
gt
;
struct
tm
tm
;
time_t
tloc
;
...
...
@@ -11,44 +11,91 @@ check(char *time_str, time_t sample) {
gt
.
buf
=
time_str
;
gt
.
size
=
strlen
(
time_str
);
tloc
=
asn_GT2time
(
&
gt
,
&
tm
);
printf
(
"[%s] -> %ld == %ld
\n
"
,
time_str
,
(
long
)
tloc
,
(
long
)
sample
);
tloc
=
asn_GT2time
(
&
gt
,
&
tm
,
as_gmt
);
printf
(
"%s: [%s] -> %ld == %ld
\n
"
,
as_gmt
?
"GMT"
:
"ofs"
,
time_str
,
(
long
)
tloc
,
(
long
)
expect
);
if
(
tloc
!=
-
1
)
printf
(
"
\t
%d-%d-%dT%02d:%02d:%02d
%ld
\n
"
,
printf
(
"
\t
%
04
d-%
02
d-%
02
dT%02d:%02d:%02d%
+03ld%02
ld
\n
"
,
tm
.
tm_year
+
1900
,
tm
.
tm_mon
+
1
,
tm
.
tm_mday
,
tm
.
tm_hour
,
tm
.
tm_min
,
tm
.
tm_sec
,
tm
.
tm_gmtoff
(
tm
.
tm_gmtoff
/
3600
),
labs
(
tm
.
tm_gmtoff
%
3600
)
);
assert
(
tloc
==
sample
);
assert
(
tloc
==
expect
);
assert
(
tloc
==
-
1
||
as_gmt
==
0
||
tm
.
tm_gmtoff
==
0
);
if
(
!
as_gmt
)
check
(
time_str
,
expect
,
1
);
}
static
void
rcheck
(
time_t
tloc
,
const
char
*
expect
,
int
force_gmt
)
{
GeneralizedTime_t
*
gt
;
struct
tm
tm
,
*
tmp
;
tmp
=
localtime_r
(
&
tloc
,
&
tm
);
assert
(
tmp
);
gt
=
asn_time2GT
(
0
,
&
tm
,
force_gmt
);
if
(
gt
)
{
assert
(
expect
);
printf
(
"[%s] vs [%s] (%d)
\n
"
,
gt
->
buf
,
expect
,
force_gmt
);
assert
(
gt
->
size
==
strlen
(
gt
->
buf
));
assert
(
!
strcmp
(
gt
->
buf
,
expect
));
}
else
{
assert
(
!
expect
);
}
}
int
main
(
int
ac
,
char
**
av
)
{
check
(
"200401250"
,
-
1
);
check
(
"2004012509300"
,
-
1
);
check
(
"20040125093000-"
,
-
1
);
check
(
"20040125093007-0"
,
-
1
);
check
(
"20040125093007-080"
,
-
1
);
check
(
"200401250930.01Z"
,
-
1
);
check
(
"200401250"
,
-
1
,
0
);
check
(
"2004012509300"
,
-
1
,
0
);
check
(
"20040125093000-"
,
-
1
,
0
);
check
(
"20040125093007-0"
,
-
1
,
0
);
check
(
"20040125093007-080"
,
-
1
,
0
);
check
(
"200401250930.01Z"
,
-
1
,
0
);
/* These six are from X.690:11.7.5 */
check
(
"19920520240000Z"
,
-
1
,
0
);
/* midnight represented incorrectly */
//check("19920622123421.0Z", -1, 0); /* spurious trailing zeros */
//check("19920722132100.30Z", -1, 0); /* spurious trailing zeros */
check
(
"19920521000000Z"
,
706406400
,
0
);
check
(
"19920622123421Z"
,
709216461
,
0
);
check
(
"19920722132100.3Z"
,
711811260
,
0
);
check
(
"20040125093007Z"
,
1075023007
);
check
(
"20040125093007+00"
,
1075023007
);
check
(
"20040125093007.01+0000"
,
1075023007
);
check
(
"20040125093007,1+0000"
,
1075023007
);
check
(
"20040125093007-0800"
,
1075051807
);
check
(
"20040125093007Z"
,
1075023007
,
0
);
check
(
"20040125093007+00"
,
1075023007
,
0
);
check
(
"20040125093007.01+0000"
,
1075023007
,
0
);
check
(
"20040125093007,1+0000"
,
1075023007
,
0
);
check
(
"20040125093007-0800"
,
1075051807
,
0
);
if
(
ac
>
1
)
{
/* These will be valid only inside PST time zone */
check
(
"20040125093007"
,
1075051807
);
check
(
"200401250930"
,
1075051800
);
check
(
"20040125093000,01"
,
1075051800
);
check
(
"20040125093000,1234"
,
1075051800
);
check
(
"20040125093007"
,
1075051807
,
0
);
check
(
"200401250930"
,
1075051800
,
0
);
check
(
"20040125093000,01"
,
1075051800
,
0
);
check
(
"20040125093000,1234"
,
1075051800
,
0
);
}
rcheck
(
1075023007
,
"20040125013007-0800"
,
0
);
rcheck
(
1075023007
,
"20040125093007Z"
,
1
);
return
0
;
}
/*
* Dummy function.
*/
der_enc_rval_t
OCTET_STRING_encode_der
(
asn1_TYPE_descriptor_t
*
td
,
void
*
ptr
,
int
tag_mode
,
ber_tlv_tag_t
tag
,
asn_app_consume_bytes_f
*
cb
,
void
*
app_key
)
{
der_enc_rval_t
erval
;
return
erval
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment