Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
asn1c
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
asn1c
Commits
99006369
Commit
99006369
authored
Aug 07, 2004
by
Lev Walkin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
improved asn_GT2time() and added asn_time2GT() function
parent
0aca3855
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
244 additions
and
51 deletions
+244
-51
ChangeLog
ChangeLog
+1
-0
skeletons/GeneralizedTime.c
skeletons/GeneralizedTime.c
+154
-28
skeletons/GeneralizedTime.h
skeletons/GeneralizedTime.h
+21
-2
skeletons/tests/check-GeneralizedTime.c
skeletons/tests/check-GeneralizedTime.c
+68
-21
No files found.
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
;
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
(
ret_tm
)
{
if
(
as_gmt
)
{
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 */
*
ret_tm
=
tm_s
;
}
else
{
if
(
gmtime_r
(
&
tloc
,
ret_tm
)
==
0
)
{
errno
=
EINVAL
;
return
-
1
;
}
}
if
(
_tm
)
memcpy
(
_tm
,
&
tm_s
,
sizeof
(
struct
tm
));
}
else
{
if
(
localtime_r
(
&
tloc
,
ret_tm
)
==
0
)
{
errno
=
EINVAL
;
return
-
1
;
}
}
}
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
%
04d-%02d-%02dT%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