提交 39cb9696 编写于 作者: C calin cerchez

finished asn

上级 a956116d
file 13724 1341839847
file 13724 1341848073
version 2
run General-0-20120709-16:16:37-6492
attr configname General
......@@ -15,116 +15,115 @@ attr replication #0
attr resultdir results
attr runnumber 0
attr seedset 0
vector 4 Test.MME.eth[0].mac framesSent ETV
4 7520 541 27 678 1.000006719999 28.908845762154 22 1 22 253 3795
vector 6 Test.MME.eth[0].mac bytesSent ETV
6 8602 583 27 678 1.000006719999 28.908845762154 22 64 2116 24154 35499636
vector 20 Test.HSS.eth[0].mac framesSent ETV
20 10825 563 28 663 1.000006719999 28.908833442155 22 1 22 253 3795
vector 22 Test.HSS.eth[0].mac bytesSent ETV
22 11951 605 28 663 1.000006719999 28.908833442155 22 64 1956 22434 29915876
vector 21 Test.HSS.eth[0].mac framesReceivedOK ETV
21 11388 563 29 679 1.000006719999 28.908845762154 22 1 22 253 3795
vector 23 Test.HSS.eth[0].mac bytesReceivedOK ETV
23 12556 605 29 679 1.000006719999 28.908845762154 22 64 2116 24154 35499636
vector 27 Test.HSS.eth[0].mac framesPassedToHL ETV
27 13161 563 29 679 1.000006719999 28.908845762154 22 1 22 253 3795
vector 5 Test.MME.eth[0].mac framesReceivedOK ETV
5 8061 541 30 664 1.000006719999 28.908833442155 22 1 22 253 3795
vector 7 Test.MME.eth[0].mac bytesReceivedOK ETV
7 9185 583 30 664 1.000006719999 28.908833442155 22 64 1956 22434 29915876
vector 11 Test.MME.eth[0].mac framesPassedToHL ETV
11 9768 563 30 664 1.000006719999 28.908833442155 22 1 22 253 3795
vector 18 Test.HSS.eth[0].queue "queue length" ETV
18 10331 494 44 412 1.000006719999 1.000142239985 20 0 2 14 18
vector 2 Test.MME.eth[0].queue "queue length" ETV
2 7047 473 46 365 1.000006719999 1.000128639987 20 0 2 14 18
vector 70 Test.HSS.sctp "Slow Start Threshold 10:192.168.1.2" ETV
70 3655 54 141 471 1.000047199995 1.000155679983 2 0 65535 65535 4294836225
vector 71 Test.HSS.sctp "Congestion Window 10:192.168.1.2" ETV
71 3709 53 141 471 1.000047199995 1.000155679983 2 0 4380 4380 19184400
vector 74 Test.HSS.sctp "HB Sent 10:192.168.1.2" ETV
74 3927 25 141 141 1.000047199995 1.000047199995 1 1 1 1 1
vector 68 Test.HSS.sctp "RTO 10:192.168.1.2" ETV
68 3762 75 141 471 1.000047199995 1.000155679983 3 0 3 4 10
vector 59 Test.MME.sctp "Slow Start Threshold 9:192.168.1.1" ETV
59 4453 173 142 687 1.000047199995 34.000047199995 6 0 65535 327675 21474181125
vector 60 Test.MME.sctp "Congestion Window 9:192.168.1.1" ETV
60 4626 168 142 687 1.000047199995 34.000047199995 6 0 4380 21900 95922000
vector 63 Test.MME.sctp "HB Sent 9:192.168.1.1" ETV
63 5416 25 142 142 1.000047199995 1.000047199995 1 1 1 1 1
vector 57 Test.MME.sctp "RTO 9:192.168.1.1" ETV
57 4794 178 142 687 1.000047199995 34.000047199995 7 0 3 8 14
vector 42 Test.MME.sctp "HB ACK Sent 5:192.168.1.1" ETV
42 4378 25 183 183 1.000054079994 1.000054079994 1 1 1 1 1
vector 43 Test.MME.sctp "HB Received 5:192.168.1.1" ETV
43 4353 25 183 183 1.000054079994 1.000054079994 1 1 1 1 1
vector 53 Test.HSS.sctp "HB ACK Sent 8:192.168.1.2" ETV
53 6717 25 184 184 1.000054079994 1.000054079994 1 1 1 1 1
vector 54 Test.HSS.sctp "HB Received 8:192.168.1.2" ETV
54 6692 25 184 184 1.000054079994 1.000054079994 1 1 1 1 1
vector 37 Test.MME.sctp "Slow Start Threshold 5:192.168.1.1" ETV
37 4055 54 211 472 1.000060799993 1.000155679983 2 0 65535 65535 4294836225
vector 38 Test.MME.sctp "Congestion Window 5:192.168.1.1" ETV
38 4109 53 211 472 1.000060799993 1.000155679983 2 0 4380 4380 19184400
vector 41 Test.MME.sctp "HB Sent 5:192.168.1.1" ETV
41 4328 25 211 211 1.000060799993 1.000060799993 1 1 1 1 1
vector 35 Test.MME.sctp "RTO 5:192.168.1.1" ETV
35 4162 75 211 472 1.000060799993 1.000155679983 3 0 3 4 10
vector 48 Test.HSS.sctp "Slow Start Threshold 8:192.168.1.2" ETV
48 5763 174 212 687 1.000060799993 34.000047199995 6 0 65535 327675 21474181125
vector 49 Test.HSS.sctp "Congestion Window 8:192.168.1.2" ETV
49 5937 169 212 687 1.000060799993 34.000047199995 6 0 4380 21900 95922000
vector 52 Test.HSS.sctp "HB Sent 8:192.168.1.2" ETV
52 6667 25 212 212 1.000060799993 1.000060799993 1 1 1 1 1
vector 46 Test.HSS.sctp "RTO 8:192.168.1.2" ETV
46 6106 153 212 687 1.000060799993 34.000047199995 6 0 3 7 13
vector 86 Test.MME.sctp "SendQueue of Association 5" ETV
86 4428 25 218 218 1.000060799993 1.000060799993 1 0 0 0 0
vector 39 Test.MME.sctp "TSN Sent 5:192.168.1.1" ETV
39 4300 28 218 218 1.000060799993 1.000060799993 1 1000 1000 1000 1000000
vector 89 Test.HSS.sctp "SendQueue of Association 8" ETV
89 6945 102 220 636 1.000060799993 28.708826562156 4 0 0 0 0
vector 50 Test.HSS.sctp "TSN Sent 8:192.168.1.2" ETV
50 6439 114 220 636 1.000060799993 28.708826562156 4 1000 1003 4006 4012014
vector 66 Test.MME.sctp "HB ACK Received 9:192.168.1.1" ETV
66 5491 25 251 251 1.000067679992 1.000067679992 1 1 1 1 1
vector 58 Test.MME.sctp "RTT 9:192.168.1.1" ETV
58 4972 218 251 687 1.000067679992 34.000047199995 6 0 0.200019199998 0.600117439987 0.1200222751551
vector 77 Test.HSS.sctp "HB ACK Received 10:192.168.1.2" ETV
77 4002 25 252 252 1.000067679992 1.000067679992 1 1 1 1 1
vector 69 Test.HSS.sctp "RTT 10:192.168.1.2" ETV
69 3837 63 252 471 1.000067679992 1.000155679983 2 0 2.0479997e-005 2.0479997e-005 4.1943027712001e-010
vector 64 Test.MME.sctp "HB ACK Sent 9:192.168.1.1" ETV
64 5466 25 271 271 1.000074559991 1.000074559991 1 1 1 1 1
vector 65 Test.MME.sctp "HB Received 9:192.168.1.1" ETV
65 5441 25 271 271 1.000074559991 1.000074559991 1 1 1 1 1
vector 75 Test.HSS.sctp "HB ACK Sent 10:192.168.1.2" ETV
75 3977 25 272 272 1.000074559991 1.000074559991 1 1 1 1 1
vector 76 Test.HSS.sctp "HB Received 10:192.168.1.2" ETV
76 3952 25 272 272 1.000074559991 1.000074559991 1 1 1 1 1
vector 62 Test.MME.sctp "TSN Received 9:192.168.1.1" ETV
62 5303 113 299 650 1.00009423999 28.708838882155 4 1000 1003 4006 4012014
vector 32 Test.MME.sctp "Advertised Receiver Window 4" ETV
32 5516 146 299 669 1.00009423999 28.908838882155 5 65375 65535 327515 21453235525
vector 73 Test.HSS.sctp "TSN Received 10:192.168.1.2" ETV
73 3900 27 300 300 1.00009423999 1.00009423999 1 1000 1000 1000 1000000
vector 33 Test.HSS.sctp "Advertised Receiver Window 7" ETV
33 4027 28 300 300 1.00009423999 1.00009423999 1 65375 65375 65375 4273890625
vector 83 Test.MME.sctp "SendQueue of Association 9" ETV
83 5662 101 314 618 1.00009423999 28.708815202157 4 0 0 0 0
vector 61 Test.MME.sctp "TSN Sent 9:192.168.1.1" ETV
61 5190 113 314 618 1.00009423999 28.708815202157 4 2000 2003 8006 16024014
vector 44 Test.MME.sctp "HB ACK Received 5:192.168.1.1" ETV
44 4403 25 339 339 1.000101119989 1.000101119989 1 1 1 1 1
vector 36 Test.MME.sctp "RTT 5:192.168.1.1" ETV
36 4237 63 339 472 1.000101119989 1.000155679983 2 0 4.0319996e-005 4.0319996e-005 1.62570207744e-009
vector 55 Test.HSS.sctp "HB ACK Received 8:192.168.1.2" ETV
55 6742 25 340 340 1.000101119989 1.000101119989 1 1 1 1 1
vector 47 Test.HSS.sctp "RTT 8:192.168.1.2" ETV
vector 51 Test.HSS.sctp "TSN Received 8:192.168.1.2" ETV
vector 45 Test.HSS.sctp "Advertised Receiver Window 8" ETV
70 3655 54 141 471 1.000047199995 1.000155679983 2 0 65535 65535 4294836225
71 3709 53 141 471 1.000047199995 1.000155679983 2 0 4380 4380 19184400
68 3762 75 141 471 1.000047199995 1.000155679983 3 0 3 4 10
69 3837 63 252 471 1.000067679992 1.000155679983 2 0 2.0479997e-005 2.0479997e-005 4.1943027712001e-010
73 3900 27 300 300 1.00009423999 1.00009423999 1 1000 1000 1000 1000000
74 3927 25 141 141 1.000047199995 1.000047199995 1 1 1 1 1
76 3952 25 272 272 1.000074559991 1.000074559991 1 1 1 1 1
75 3977 25 272 272 1.000074559991 1.000074559991 1 1 1 1 1
77 4002 25 252 252 1.000067679992 1.000067679992 1 1 1 1 1
33 4027 28 300 300 1.00009423999 1.00009423999 1 65375 65375 65375 4273890625
37 4055 54 211 472 1.000060799993 1.000155679983 2 0 65535 65535 4294836225
38 4109 53 211 472 1.000060799993 1.000155679983 2 0 4380 4380 19184400
35 4162 75 211 472 1.000060799993 1.000155679983 3 0 3 4 10
36 4237 63 339 472 1.000101119989 1.000155679983 2 0 4.0319996e-005 4.0319996e-005 1.62570207744e-009
39 4300 28 218 218 1.000060799993 1.000060799993 1 1000 1000 1000 1000000
41 4328 25 211 211 1.000060799993 1.000060799993 1 1 1 1 1
43 4353 25 183 183 1.000054079994 1.000054079994 1 1 1 1 1
42 4378 25 183 183 1.000054079994 1.000054079994 1 1 1 1 1
44 4403 25 339 339 1.000101119989 1.000101119989 1 1 1 1 1
86 4428 25 218 218 1.000060799993 1.000060799993 1 0 0 0 0
59 4453 173 142 687 1.000047199995 34.000047199995 6 0 65535 327675 21474181125
60 4626 168 142 687 1.000047199995 34.000047199995 6 0 4380 21900 95922000
57 4794 178 142 687 1.000047199995 34.000047199995 7 0 3 8 14
58 4972 218 251 687 1.000067679992 34.000047199995 6 0 0.200019199998 0.600117439987 0.1200222751551
61 5190 113 314 618 1.00009423999 28.708815202157 4 2000 2003 8006 16024014
62 5303 113 299 650 1.00009423999 28.708838882155 4 1000 1003 4006 4012014
63 5416 25 142 142 1.000047199995 1.000047199995 1 1 1 1 1
65 5441 25 271 271 1.000074559991 1.000074559991 1 1 1 1 1
64 5466 25 271 271 1.000074559991 1.000074559991 1 1 1 1 1
66 5491 25 251 251 1.000067679992 1.000067679992 1 1 1 1 1
32 5516 146 299 669 1.00009423999 28.908838882155 5 65375 65535 327515 21453235525
83 5662 101 314 618 1.00009423999 28.708815202157 4 0 0 0 0
48 5763 174 212 687 1.000060799993 34.000047199995 6 0 65535 327675 21474181125
49 5937 169 212 687 1.000060799993 34.000047199995 6 0 4380 21900 95922000
46 6106 153 212 687 1.000060799993 34.000047199995 6 0 3 7 13
47 6259 180 340 687 1.000101119989 34.000047199995 5 0 0.200019199998 0.60009695999 0.12002265869328
50 6439 114 220 636 1.000060799993 28.708826562156 4 1000 1003 4006 4012014
vector 51 Test.HSS.sctp "TSN Received 8:192.168.1.2" ETV
51 6553 114 372 632 1.000128639987 28.708826562156 4 2000 2003 8006 16024014
52 6667 25 212 212 1.000060799993 1.000060799993 1 1 1 1 1
54 6692 25 184 184 1.000054079994 1.000054079994 1 1 1 1 1
53 6717 25 184 184 1.000054079994 1.000054079994 1 1 1 1 1
55 6742 25 340 340 1.000101119989 1.000101119989 1 1 1 1 1
vector 45 Test.HSS.sctp "Advertised Receiver Window 8" ETV
45 6767 178 372 654 1.000128639987 28.908826562156 6 65363 65535 393038 25746502894
89 6945 102 220 636 1.000060799993 28.708826562156 4 0 0 0 0
2 7047 473 46 365 1.000006719999 1.000128639987 20 0 2 14 18
4 7520 541 27 678 1.000006719999 28.908845762154 22 1 22 253 3795
5 8061 541 30 664 1.000006719999 28.908833442155 22 1 22 253 3795
6 8602 583 27 678 1.000006719999 28.908845762154 22 64 2116 24154 35499636
7 9185 583 30 664 1.000006719999 28.908833442155 22 64 1956 22434 29915876
11 9768 563 30 664 1.000006719999 28.908833442155 22 1 22 253 3795
18 10331 494 44 412 1.000006719999 1.000142239985 20 0 2 14 18
20 10825 563 28 663 1.000006719999 28.908833442155 22 1 22 253 3795
21 11388 563 29 679 1.000006719999 28.908845762154 22 1 22 253 3795
22 11951 605 28 663 1.000006719999 28.908833442155 22 64 1956 22434 29915876
23 12556 605 29 679 1.000006719999 28.908845762154 22 64 2116 24154 35499636
27 13161 563 29 679 1.000006719999 28.908845762154 22 1 22 253 3795
//
// Copyright (C) 2012 Calin Cerchez
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
......
......@@ -51,17 +51,32 @@ enum ObjectType {
*/
/*
* Method for counting the bits needed to represent a certain value.
* Method for counting the bits, needed to represent a certain value.
*/
int64_t countBits(int64_t value, int64_t count);
class PerEncoder;
/*
* Base class for ASN.1 types. All ASN.1 types will be derived from this class and they
* will be differentiated based on the tag value. Information about the particular ASN.1
* type will be stored in the Info structure defined in each individual class.
*/
class AbstractType {
public:
/*
* Method for creating ASN.1 types. The ASN.1 type will be created
* based on the information provided to this method. This information
* cannot be changed afterwards for this particular object.
*/
inline static AbstractType* create(const void* info) { return info ? static_cast<const Info*>(info)->create(info) : 0; }
typedef AbstractType* (*CreateAbstractType)(const void*);
protected:
/*
* Info structure will hold all the information necessary for
* each ASN.1 type, including tag, type, flags, constraints,
* and will change accordingly.
*/
struct Info {
CreateAbstractType create;
char tag;
......@@ -72,11 +87,11 @@ public:
AbstractType(const void *info) { this->info = info; }
virtual ~AbstractType() {}
/* getter */
/* Getter methods. */
char getTag() const { return getInfo()->tag; }
const Info *getInfo() const { return static_cast<const Info*>(info); }
/* utility */
/* Utility methods. */
virtual AbstractType *clone() const = 0;
virtual int64_t compare(const AbstractType& other) const = 0;
};
......@@ -91,6 +106,9 @@ public:
// static const Info theInfo;
//};
/*
* Base class for all constrained ASN.1 types.
*/
class ConstrainedType : public AbstractType {
protected:
struct Info {
......@@ -103,8 +121,9 @@ protected:
};
public:
ConstrainedType(const void *info) : AbstractType(info) {}
virtual ConstrainedType() {}
/* getter */
/* Getter methods. */
char getConstraintType() const { return getInfo()->type; }
int64_t getLowerBound() const { return getInfo()->lowerBound; }
int64_t getUpperBound() const { return getInfo()->upperBound; }
......@@ -113,10 +132,9 @@ public:
};
/**********************************/
/* Class for ASN.1 OpenType type */
/**********************************/
/*
* Class for ASN.1 Open type field.
*/
class OpenType : public AbstractType {
private:
int64_t length;
......@@ -124,64 +142,67 @@ private:
public:
static const Info theInfo;
/* Constructors. */
OpenType(const void *info = &theInfo) : AbstractType(info) {}
OpenType(char *val, int64_t len, const void *info = &theInfo);
OpenType(AbstractType *val, const void *info = &theInfo);
OpenType(const OpenType& other) : AbstractType(other) { operator=(other); }
virtual ~OpenType() {}
/* operator */
/* Operator methods. */
OpenType &operator=(const OpenType& other);
// OpenType &operator=(const AbstractType &other);
/* setter */
/* Setter methods. */
void setValue(char *value) { this->value = value; }
void setLength(int64_t length) { this->length = length; }
/* getter */
/* Getter methods. */
char *getValue() const { return value; }
int64_t getLength() const { return length; }
/* utility */
/* Utility methods. */
virtual AbstractType *clone() const { return new OpenType(*this); }
virtual int64_t compare(const AbstractType& other) const;
static AbstractType *create(const void *info) { return new OpenType(info); }
/* encoding */
/* Wrapper methods. */
bool decode(char *buffer);
bool encode(PerEncoder& encoder) const;
};
/********************************/
/* Class for ASN.1 INTEGER type */
/********************************/
/*
* Class for ASN.1 Integer type.
*/
class IntegerBase : public ConstrainedType {
private:
int64_t value;
public:
static const Info theInfo;
/* Constructors. */
IntegerBase(const void *info = &theInfo) : ConstrainedType(info) {}
IntegerBase(int64_t value, const void *info = &theInfo) : ConstrainedType(info) { setValue(value); }
IntegerBase(const IntegerBase& other) : ConstrainedType(other) { operator=(other); }
virtual ~IntegerBase() {}
/* operator */
/* Operator methods. */
IntegerBase &operator=(const IntegerBase &other);
/* getter */
/* Getter methods. */
int64_t getValue() const { return value; }
/* setter */
/* Setter methods. */
void setValue(int64_t value) { this->value = value; }
/* utility */
/* Utility methods. */
virtual AbstractType *clone() const { return new IntegerBase(*this); }
virtual int64_t compare(const AbstractType& other) const;
static AbstractType *create(const void *info) { return new IntegerBase(info); }
/* encoding */
/* Wrapper methods. */
bool decode(char *buffer);
bool encode(PerEncoder& encoder) const;
};
......@@ -203,10 +224,9 @@ const typename Integer<type, lowerBound, upperBound>::Info Integer<type, lowerBo
upperBound
};
/***********************************/
/* Class for ASN.1 ENUMERATED type */
/***********************************/
/*
* Class for ASN.1 Enumerated type.
*/
class EnumeratedBase : public AbstractType {
private:
int64_t value;
......@@ -219,28 +239,30 @@ protected:
int64_t upperBound;
};
public:
/* Constructors. */
EnumeratedBase(const void *info) : AbstractType(info) {}
EnumeratedBase(const EnumeratedBase& other) : AbstractType(other) { operator=(other); }
virtual ~EnumeratedBase() {}
/* operator */
/* Operator methods. */
EnumeratedBase &operator=(const EnumeratedBase& other);
/* getter */
/* Getter methods. */
int64_t getValue() const { return value; }
bool isExtendable() const { return getInfo()->extFlag; }
int64_t getUpperBound() const { return getInfo()->upperBound; }
const Info* getInfo() const { return static_cast<const Info*>(info); }
/* setter */
/* Setter methods. */
void setValue(int64_t value) { this->value = value; }
/* utility */
/* Utility methods. */
virtual AbstractType *clone() const { return new EnumeratedBase(*this); }
virtual int64_t compare(const AbstractType& other) const;
static AbstractType *create(const void *info) { return new EnumeratedBase(info); }
/* encoding */
/* Wrapper methods. */
bool decode(char *buffer);
bool encode(PerEncoder& encoder) const;
};
......@@ -263,10 +285,9 @@ const typename Enumerated<ext, upperBound>::Info Enumerated<ext, upperBound>::th
upperBound
};
/**********************************/
/* Class for ASN.1 BITSTRING type */
/**********************************/
/*
* Class for ASN.1 Bitstring type.
*/
class BitStringBase : public ConstrainedType {
protected:
int64_t length;
......@@ -274,32 +295,34 @@ protected:
public:
static const Info theInfo;
/* Constructors. */
BitStringBase(const void *info = &theInfo);
BitStringBase(const BitStringBase& other) : ConstrainedType(other) { operator=(other); }
virtual ~BitStringBase() {}
/* operator */
/* Operator methods. */
BitStringBase& operator=(const BitStringBase& other);
// bool operator==(const BitStringBase& other) const { return compare(other) == 0; }
/* getter */
/* Getter methods. */
int64_t getLength() const { return length; }
char *getValue() const { return value; }
bool getBit(int64_t index) const;
/* setter */
/* Setter methods. */
void setValue(char *value) { this->value = value; }
void setLength(int64_t length) { this->length = length; }
void setBit(int64_t index, bool bit);
int64_t resize(int64_t length);
/* utility */
/* Utility methods. */
virtual AbstractType *clone() const { return new BitStringBase(*this); }
virtual int64_t compare(const AbstractType& other) const;
static AbstractType *create(const void *info) { return new BitStringBase(info); }
void print();
/* encoding */
/* Wrapper methods. */
bool decode(char *buffer);
bool encode(PerEncoder& encoder) const;
};
......@@ -321,10 +344,9 @@ const typename BitString<type, lowerBound, upperBound>::Info BitString<type, low
upperBound
};
/************************************/
/* Class for ASN.1 OCTETSTRING type */
/************************************/
/*
* Class for ASN.1 Octetstring type.
*/
class OctetStringBase : public ConstrainedType {
protected:
int64_t length;
......@@ -332,28 +354,30 @@ protected:
public:
static const Info theInfo;
/* Constructors. */
OctetStringBase(const void *info = &theInfo);
OctetStringBase(const OctetStringBase& other) : ConstrainedType(other) { operator=(other); }
virtual ~OctetStringBase() {}
/* operator */
/* Operator methods. */
OctetStringBase& operator=(const OctetStringBase& other);
// bool operator==(const OctetStringBase& other) const { return compare(other) == 0; }
/* getter */
/* Getter methods. */
int64_t getLength() const { return length; }
char *getValue() const { return value; }
/* setter */
/* Setter methods. */
void setValue(char *value) { this->value = value; }
void setLength(int64_t length) { this->length = length; }
/* utility */
/* Utility methods. */
virtual AbstractType *clone() const { return new OctetStringBase(*this); }
virtual int64_t compare(const AbstractType& other) const;
static AbstractType *create(const void *info) { return new OctetStringBase(info); }
/* encoding */
/* Wrapper methods. */
bool decode(char *buffer);
bool encode(PerEncoder& encoder) const;
};
......@@ -388,40 +412,41 @@ const typename OctetString<type, lowerBound, upperBound>::Info OctetString<type,
// static AbstractType *create(const void *info) { return new AbstractString(info); }
//};
/****************************************/
/* Class for ASN.1 PrintableString type */
/****************************************/
/*
* Class for ASN.1 Printablestring type.
*/
class PrintableStringBase : public ConstrainedType {
private:
std::string value;
public:
static const Info theInfo;
/* Constructors. */
PrintableStringBase(const void *info = &theInfo) : ConstrainedType(info) {}
PrintableStringBase(std::string value, const void *info = &theInfo) : ConstrainedType(info) { setValue(value); }
PrintableStringBase(const char *value, const void *info = &theInfo) : ConstrainedType(info) { setValue(value); }
PrintableStringBase(const PrintableStringBase& other) : ConstrainedType(other) { operator=(other); }
virtual ~PrintableStringBase() {}
/* operator */
/* Operator methods. */
PrintableStringBase& operator=(const PrintableStringBase& other);
// bool operator==(const PrintableStringBase& other) const { return compare(other) == 0; }
/* getter */
/* Getter methods. */
int64_t getLength() const { return value.size(); }
std::string getValue() const { return value; }
/* setter */
/* Setter methods. */
void setValue(std::string value) { this->value = value; }
void print() { printf("%s\n", value.c_str()); }
/* utility */
/* Utility methods. */
virtual AbstractType *clone() const { return new PrintableStringBase(*this); }
virtual int64_t compare(const AbstractType& other) const;
static AbstractType *create(const void *info) { return new PrintableStringBase(info); }
/* encoding */
/* Wrapper methods. */
bool decode(char *buffer);
bool encode(PerEncoder& encoder) const;
};
......@@ -444,14 +469,13 @@ const typename PrintableString<type, lowerBound, upperBound>::Info PrintableStri
upperBound
};
/*********************************/
/* Class for ASN.1 SEQUENCE type */
/*********************************/
/*
* Class for ASN.1 Sequence type.
*/
class Sequence : public AbstractType {
protected:
char *optFlags;
char *extFlags;
char *optFlags; // holds optional and default bits
char *extFlags; // holds extension presence bits
std::vector<AbstractType*> items;
struct Info {
CreateAbstractType create;
......@@ -465,11 +489,13 @@ protected:
int64_t sizeExt;
};
public:
/* Constructors */
Sequence(const void *info);
Sequence(const Sequence& other);
virtual ~Sequence() {}
/* getter */
/* Getter methods. */
AbstractType *at(int64_t index) const { return items.at(index); }
int64_t getLength() const { return items.size(); }
char *getOptFlags() const { return optFlags; }
......@@ -479,24 +505,24 @@ public:
bool getOptFlag(int64_t index) const;
const Info* getInfo() const { return static_cast<const Info*>(info);}
/* setter */
/* Setter methods. */
void setOptFlag(int64_t index, bool bit);
// bool operator==(const Sequence& other) const { return compare(other); }
/* Utility methods. */
virtual AbstractType *clone() const { return new Sequence(*this); }
virtual int64_t compare(const AbstractType& other) const;
static AbstractType *create(const void *info) { return new Sequence(info); }
/* encoding */
/* Wrapper methods. */
bool decode(char *buffer);
bool encode(PerEncoder& encoder) const;
};
/***********************************/
/* Class for ASN.1 SEQUENCEOF type */
/***********************************/
/*
* Class for ASN.1 Sequenceof type.
*/
class SequenceOfBase : public ConstrainedType {
protected:
typedef std::vector<AbstractType*> Container;
......@@ -511,26 +537,27 @@ protected:
const void* itemInfo;
};
public:
/* Constructors. */
SequenceOfBase(const void *info) : ConstrainedType(info) {}
SequenceOfBase(const SequenceOfBase& other);
virtual ~SequenceOfBase() {}
/* getter */
/* Getter methods. */
int64_t size() const { return items.size(); }
AbstractType *at(int64_t it) const { return items.at(it); }
void pop_back() { items.pop_back(); }
const Info* getInfo() const { return static_cast<const Info*>(info); }
/* setter */
/* Setter methods. */
void push_back(AbstractType *item) { items.push_back(item); }
/* utils */
/* Utility methods. */
virtual AbstractType *clone() const { return new SequenceOfBase(*this); }
virtual int64_t compare(const AbstractType& other) const;
static AbstractType *create(const void *info) { return new SequenceOfBase(info); }
AbstractType * createItem() const;
/*encoding */
/* Wrapper methods. */
bool decode(char *buffer);
bool encode(PerEncoder& encoder) const;
};
......@@ -564,10 +591,9 @@ const typename SequenceOf<T, type, lowerBound, upperBound>::Info SequenceOf<T, t
&T::theInfo
};
/*******************************/
/* Class for ASN.1 CHOICE type */
/*******************************/
/*
* Class for ASN.1 Choice type.
*/
class Choice : public AbstractType {
protected:
int64_t choice;
......@@ -581,28 +607,30 @@ protected:
int64_t upperBound;
};
public:
/* Constructors */
Choice(const void *info, int64_t choice = -1, AbstractType *value = NULL);
Choice(const Choice& other);
virtual ~Choice() {}
/* getter */
/* Getter methods. */
AbstractType *getValue() const { return value; }
int64_t getChoice() const { return choice; }
bool isExtendable() const { return getInfo()->extFlag; }
int64_t getUpperBound() const { return getInfo()->upperBound; }
const Info* getInfo() const { return static_cast<const Info*>(info);}
/* setter */
/* Setter methods. */
void setValue(AbstractType *value, int64_t choice) { this->choice = choice; this->value = value; }
void createChoice(int64_t choice) { this->choice = choice; createValue(); }
void createValue();
/* utils */
/* Utility methods. */
virtual AbstractType *clone() const { return new Choice(*this); }
virtual int64_t compare(const AbstractType& other) const;
static AbstractType *create(const void *info) { return new Choice(info); }
/* encoding */
/* Wrapper methods. */
bool decode(char *buffer);
bool encode(PerEncoder& encoder) const;
};
......
//
// Copyright (C) 2012 Calin Cerchez
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
......@@ -15,8 +17,8 @@
#include "PerDecoder.h"
PerDecoder::PerDecoder(char *val) {
this->val = val;
PerDecoder::PerDecoder(char *buffer) {
this->buffer = buffer;
this->it = 0;
leftBits = 8;
}
......@@ -25,37 +27,162 @@ PerDecoder::~PerDecoder() {
}
//bool PerDecoder::decodeExtension(ConstrainedType *constrainedType) {
// if (constrainedType->getConstraintType() == EXTCONSTRAINED) {
// BitString<CONSTRAINED, 1, 1> *extBit = new BitString<CONSTRAINED, 1, 1>(1);
//
// if (!decodeBitString(extBit))
// return false;
// abstractType->setExtension(extBit->getBit(0));
// }
// return true;
//}
int64_t PerDecoder::decodeConstrainedValue(int64_t lowerBound, int64_t upperBound) {
int64_t range = upperBound - lowerBound + 1;
int64_t length;
int64_t value;
if (range < 2) {
return 0;
} else if (range < 256) {
int64_t numBits = countBits(range - 1, 0);
value = (decodeBits(numBits) >> (8 - numBits)) + lowerBound;
} else if (range < 65537) {
length = (countBits(range - 1, 0) + 7) / 8;
value = decodeValue(length) + lowerBound;
} else {
length = decodeLength((countBits(lowerBound, 0) + 7) / 8, (countBits(upperBound, 0) + 7) / 8);
value = decodeValue(length) + lowerBound;
}
return value;
}
int64_t PerDecoder::decodeUnconstrainedValue() {
return decodeValue(decodeLength(0, INT_MAX));
}
char *PerDecoder::decodeSmallBitString(unsigned char length) {
char *buffer = (char*)calloc((length + 7) / 8, sizeof(char));
if (length < 9) {
*buffer = decodeBits(length);
} else {
*buffer = decodeBits(8);
*(buffer + 1) = decodeBits(length - 8);
}
return buffer;
}
char *PerDecoder::decodeBytes(int64_t length) {
// gets the buffer from iterator position and moves the iterator
allignIterator();
char *buffer = (char *)calloc(sizeof(char), length);
memcpy(buffer, this->buffer + it, length);
it += length;
return buffer;
}
unsigned char PerDecoder::decodeBits(unsigned char length) {
// returns a maximum of 8 bits from the tail of the buffer
// the bits are shifted 1100....
unsigned char value = 0;
// if it has to read bits also from the next byte in the buffer
if (leftBits - length < 0) {
// takes the bits from the current byte and moves the iterator
value = ((unsigned char)this->buffer[it++] << (8 - leftBits));
// takes the bits also from the next byte
value += ((unsigned char)this->buffer[it] >> leftBits);
// changes the number of left bits in the iterator byte
leftBits = (8 - (length - leftBits));
// all the bits are in the same byte
} else {
value = (unsigned char)((this->buffer[it] & bitMask(leftBits - length, leftBits)) << (8 - leftBits));
leftBits -= length;
// if there are no more bits to read in the iterator byte
// reset the number of left bits to 8 and move the iterator
if (!leftBits) {
leftBits = 8;
it++;
}
}
return value;
}
int64_t PerDecoder::decodeValue(int64_t length) {
int64_t val = 0;
allignIterator();
for (int i = length - 1; i >= 0; i--) {
val += ((1 << (8 * i))) * ((int64_t )*(this->buffer + it++));
}
return val;
}
int64_t PerDecoder::decodeSmallNumber() {
int64_t value;
if ((*(this->buffer + it) << (8 - leftBits)) < 128) {
value = (decodeBits(7) >> 1);
} else {
it++;
value = decodeLength(0, INT_MAX);
}
return value;
}
int64_t PerDecoder::decodeLength(int64_t lowerBound, int64_t upperBound) {
int64_t length;
if (upperBound > 65535) {
allignIterator();
if ((unsigned char)*(buffer + it) < 128) {
length = decodeValue(1);
} else if ((unsigned char)*(buffer + it) < 192) {
length = decodeValue(2) - 32768;
} else { /* FIXME */
while ((unsigned char)*(buffer + it) > 191) {
length += (decodeValue(1) - 192) * 16384;
}
length += decodeLength(0, INT_MAX);
}
} else {
length = decodeConstrainedValue(lowerBound, upperBound);
}
return length;
}
unsigned char PerDecoder::bitMask(unsigned char start, unsigned char end) {
unsigned char mask = ((1 << (end - start)) - 1);
return mask << start;
}
void PerDecoder::allignIterator() {
if (leftBits != 8) {
it++;
leftBits = 8;
}
}
bool PerDecoder::decodeAbstractType(AbstractType& abstractType) {
switch(abstractType.getTag()) {
case INTEGER:
return decodeInteger(static_cast<IntegerBase&>(abstractType));
return decodeInteger(dynamic_cast<IntegerBase&>(abstractType));
case ENUMERATED:
return decodeEnumerated(static_cast<EnumeratedBase&>(abstractType));
return decodeEnumerated(dynamic_cast<EnumeratedBase&>(abstractType));
case BITSTRING:
return decodeBitString(static_cast<BitStringBase&>(abstractType));
return decodeBitString(dynamic_cast<BitStringBase&>(abstractType));
case OCTETSTRING:
return decodeOctetString(static_cast<OctetStringBase&>(abstractType));
return decodeOctetString(dynamic_cast<OctetStringBase&>(abstractType));
case SEQUENCE:
return decodeSequence(static_cast<Sequence&>(abstractType));
return decodeSequence(dynamic_cast<Sequence&>(abstractType));
case SEQUENCEOF:
return decodeSequenceOf(static_cast<SequenceOfBase&>(abstractType));
return decodeSequenceOf(dynamic_cast<SequenceOfBase&>(abstractType));
case CHOICE:
return decodeChoice(static_cast<Choice&>(abstractType));
return decodeChoice(dynamic_cast<Choice&>(abstractType));
case PRINTABLESTRING:
return decodePrintableString(static_cast<PrintableStringBase&>(abstractType));
return decodePrintableString(dynamic_cast<PrintableStringBase&>(abstractType));
case OPENTYPE:
return decodeOpenType(static_cast<OpenType&>(abstractType));
return decodeOpenType(dynamic_cast<OpenType&>(abstractType));
default:
return false;
}
......@@ -64,35 +191,11 @@ bool PerDecoder::decodeAbstractType(AbstractType& abstractType) {
bool PerDecoder::decodeOpenType(OpenType& openType) {
openType.setLength(decodeLength(0, INT_MAX));
openType.setValue(val + it);
openType.setValue(buffer + it);
it += openType.getLength();
return true;
}
int64_t PerDecoder::decodeConstrainedValue(int64_t lowerBound, int64_t upperBound) {
int64_t range = upperBound - lowerBound + 1;
int64_t len;
int64_t val;
if (range < 2) {
return 0;
} else if (range < 256) {
int64_t numBits = countBits(range - 1, 0);
val = (decodeBits(numBits) >> (8 - numBits)) + lowerBound;
} else if (range < 65537) {
len = (countBits(range - 1, 0) + 7) / 8;
val = decodeValue(len) + lowerBound;
} else {
len = decodeLength((countBits(lowerBound, 0) + 7) / 8, (countBits(upperBound, 0) + 7) / 8);
val = decodeValue(len) + lowerBound;
}
return val;
}
int64_t PerDecoder::decodeUnconstrainedValue() {
return decodeValue(decodeLength(0, INT_MAX));
}
bool PerDecoder::decodeInteger(IntegerBase& integer) {
if ((integer.isExtendable() && decodeBits(1))
|| integer.getConstraintType() > EXTCONSTRAINED)
......@@ -110,21 +213,6 @@ bool PerDecoder::decodeEnumerated(EnumeratedBase& enumerated) {
return true;
}
char *PerDecoder::decodeSmallBitString(unsigned char len) {
char *buffer = (char*)calloc((len + 7) / 8, sizeof(char));
if (len < 9) {
*buffer = decodeBits(len);
} else {
*buffer = decodeBits(8);
*(buffer + 1) = decodeBits(len - 8);
}
return buffer;
}
//bool PerDecoder::decodeConstrainedBitString(BitStringBase *bitString) {
//
//}
bool PerDecoder::decodeBitString(BitStringBase& bitString) {
if ((bitString.isExtendable() && decodeBits(1))
|| (bitString.getLowerBound() != bitString.getUpperBound())
......@@ -145,10 +233,6 @@ bool PerDecoder::decodeBitString(BitStringBase& bitString) {
return true;
}
//bool PerDecoder::decodeConstrainedOctetString(OctetStringBase *octetString) {
//
//}
bool PerDecoder::decodeOctetString(OctetStringBase& octetString) {
if ((octetString.isExtendable() && decodeBits(1))
|| (octetString.getLowerBound() != octetString.getUpperBound())
......@@ -169,15 +253,8 @@ bool PerDecoder::decodeOctetString(OctetStringBase& octetString) {
return true;
}
//bool PerDecoder::decodeSequenceHeader(Sequence *sequence) {
// if (!decodeExtension(sequence))
// return false;
// if (!decodeBitString(sequence.getRootFlags()))
// return false;
// return true;
//}
//
bool PerDecoder::decodeSequence(Sequence& sequence) {
// TODO add support for extension
bool hasExtension = false;
if (sequence.isExtendable() && decodeBits(1))
hasExtension = true;
......@@ -261,7 +338,7 @@ bool PerDecoder::decodeChoiceValue(Choice& choice) {
}
bool PerDecoder::decodeChoice(Choice& choice) {
/* TODO add support for extension */
// TODO add support for extension
if (!decodeChoiceValue(choice))
return false;
......@@ -300,88 +377,3 @@ bool PerDecoder::decodePrintableString(PrintableStringBase& printableString) {
return true;
}
char *PerDecoder::decodeBytes(int64_t len) {
allignIterator();
char *val = (char *)calloc(sizeof(char), len);
memcpy(val, this->val + it, len);
it += len;
return val;
}
unsigned char PerDecoder::decodeBits(unsigned char len) {
unsigned char val = 0;
if (leftBits - len < 0) {
val = ((unsigned char)this->val[it++] << (8 - leftBits));
val += ((unsigned char)this->val[it] >> leftBits);
leftBits = (8 - (len - leftBits));
} else {
val = (unsigned char)((this->val[it] & bitMask(leftBits - len, leftBits)) << (8 - leftBits));
leftBits -= len;
if (!leftBits) {
leftBits = 8;
it++;
}
}
return val;
}
int64_t PerDecoder::decodeValue(int64_t len) {
int64_t val = 0;
allignIterator();
for (int i = len - 1; i >= 0; i--) {
val += ((1 << (8 * i))) * ((int64_t )*(this->val + it++));
}
return val;
}
int64_t PerDecoder::decodeSmallNumber() {
int64_t val;
if ((*(this->val + it) << (8 - leftBits)) < 128) {
val = (decodeBits(7) >> 1);
} else {
it++;
val = decodeLength(0, INT_MAX);
}
return val;
}
int64_t PerDecoder::decodeLength(int64_t lowerBound, int64_t upperBound) {
int64_t len;
if (upperBound > 65535) {
allignIterator();
if ((unsigned char)*(val + it) < 128) {
len = decodeValue(1);
} else if ((unsigned char)*(val + it) < 192) {
len = decodeValue(2) - 32768;
} else { /* FIXME */
while ((unsigned char)*(val + it) > 191) {
len += (decodeValue(1) - 192) * 16384;
}
len += decodeLength(0, INT_MAX);
}
} else {
len = decodeConstrainedValue(lowerBound, upperBound);
}
return len;
}
unsigned char PerDecoder::bitMask(unsigned char start, unsigned char end) {
unsigned char mask = ((1 << (end - start)) - 1);
return mask << start;
}
void PerDecoder::allignIterator() {
if (leftBits != 8) {
it++;
leftBits = 8;
}
}
//
// Copyright (C) 2012 Calin Cerchez
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
......@@ -22,46 +24,52 @@
#include <limits.h>
#include "ASNTypes.h"
/*
* Class for decoding an ASN.1 PER encoded byte string. The class will parse the
* buffer and decode each required ASN.1 type, moving the iterator and changing
* the number of left bits in the iterator byte if necessary, accordingly. During the
* decoding the class will store the information in the desired ASN.1 object.
* More information about decoding rules can be found in X691 specification.
*/
class PerDecoder {
private:
char *buffer;
int64_t it;
short leftBits;
/* Utility methods for decoding. */
int64_t decodeConstrainedValue(int64_t lowerBound, int64_t upperBound);
int64_t decodeUnconstrainedValue();
int64_t decodeValue(int64_t length);
int64_t decodeSmallNumber();
int64_t decodeLength(int64_t lowerBound, int64_t upperBound);
char *decodeSmallBitString(unsigned char length);
char *decodeBytes(int64_t length);
unsigned char decodeBits(unsigned char length);
/* Utility methods. */
unsigned char bitMask(unsigned char start, unsigned char end);
void allignIterator();
public:
PerDecoder(char *val);
virtual ~PerDecoder();
/* Decoding methods. */
bool decodeAbstractType(AbstractType& abstractType);
bool decodeOpenType(OpenType& openType);
bool decodeInteger(IntegerBase& integer);
bool decodeEnumerated(EnumeratedBase& enumerated);
bool decodeBitString(BitStringBase& bitString);
bool decodeOctetString(OctetStringBase& octetString);
// bool decodeSequenceHeader(Sequence *sequence);
bool decodeSequence(Sequence& sequence);
int64_t decodeSequenceOfSize(SequenceOfBase& sequenceOf);
bool decodeSequenceOf(SequenceOfBase& sequenceOf);
bool decodeChoiceValue(Choice& choice);
bool decodeChoice(Choice& choice);
bool decodePrintableString(PrintableStringBase& printableString);
private:
char *val;
int64_t it;
short leftBits;
// bool decodeExtension(ConstrainedType *constrainedType);
int64_t decodeConstrainedValue(int64_t lowerBound, int64_t upperBound);
int64_t decodeUnconstrainedValue();
char *decodeSmallBitString(unsigned char len);
// bool decodeConstrainedBitString(BitStringBase *bitString);
// bool decodeConstrainedOctetString(OctetStringBase *octetString);
unsigned char bitMask(unsigned char start, unsigned char end);
char *decodeBytes(int64_t len);
void allignIterator();
unsigned char decodeBits(unsigned char len);
int64_t decodeValue(int64_t len);
int64_t decodeSmallNumber();
int64_t decodeLength(int64_t lowerBound, int64_t upperBound);
int64_t decodeSequenceOfSize(SequenceOfBase& sequenceOf);
bool decodeChoiceValue(Choice& choice);
};
#endif /* PERDECODER_H_ */
//
// Copyright (C) 2012 Calin Cerchez
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
......@@ -18,15 +20,164 @@
PerEncoder::PerEncoder() {
usedBits = 8;
len = 0;
val = (char *)calloc(len, sizeof(char));
length = 0;
buffer = NULL;
}
PerEncoder::~PerEncoder() {
}
bool PerEncoder::encodeConstrainedValue(int64_t lowerBound, int64_t upperBound, int64_t value) {
int64_t range = upperBound - lowerBound + 1;
value -= lowerBound;
int64_t bitCount;
if (range < 2) {
return true;
} else if (range < 256) {
bitCount = countBits(range - 1, 0);
value <<= (8 - bitCount);
encodeBits(value, bitCount);
} else if (range < 65537) {
bitCount = (countBits(range - 1, 0) + 7) / 8;
encodeValue(value, bitCount);
} else {
bitCount = (countBits(value, 0) + 7) / 8;
if (!encodeLength(bitCount, (countBits(lowerBound, 0) + 7) / 8, (countBits(upperBound, 0) + 7) / 8))
return false;
encodeValue(value, bitCount);
}
return true;
}
bool PerEncoder::encodeUnconstrainedValue(int64_t value) {
int64_t bitCount = (countBits(value, 0) + 7) / 8;
if (!encodeLength(bitCount, 0, INT_MAX))
return false;
encodeValue(value, bitCount);
return true;
}
void PerEncoder::encodeSmallBitString(char *value, unsigned char length) {
if (length < 9) {
encodeBits(*value, length);
} else {
encodeBits(*value, 8);
encodeBits(*(value + 1), length - 8);
}
}
void PerEncoder::print(bool type) {
if (type == BIN) {
// for (int64_t i = 0; i < len; i++) {
// for (short j = 7; j >= 0; j--) {
// if ((data[i] & (1 << j)) == 0)
// printf("0");
// else
// printf("1");
// }
// printf(" ");
// }
} else {
char buffer[length * 3 + 1];
int j = 0;
for (int i = 0; i < length; i++, j += 3)
sprintf(&buffer[j], " %02x ", (unsigned char)this->buffer[i]);
buffer[length * 3] = '\0';
EV << buffer;
}
EV << endl;
}
void PerEncoder::encodeBytes(const char *value, int64_t length) {
// appends the bytes to the buffer and increases the size of it
this->buffer = (char *)realloc(this->buffer, this->length + length);
memcpy(this->buffer + this->length, value, length);
this->length += length;
usedBits = 8;
}
bool PerEncoder::encodeSmallNumber(int64_t value) {
if (value) {
value = value << 1;
encodeBits((unsigned char )value, 7);
} else {
encodeBits(128, 1);
if (encodeLength(value, 0, INT_MAX) < 0)
return false;
}
return true;
}
bool PerEncoder::encodeLength(int64_t length, int64_t lowerBound, int64_t upperBound) {
if (upperBound > 65535) {
if (length) {
encodeValue(length, 1);
} else if (length < 16384) {
length += 32768;
encodeValue(length, 2);
} else {
for (unsigned char f = 4; f > 0; f--) {
while((length - f * 16384) >= 0) {
length -= f * 16384;
char tmp = (char )(192 + f);
encodeBytes(&tmp, 1);
}
}
encodeLength(length, lowerBound, upperBound);
}
} else {
return encodeConstrainedValue(lowerBound, upperBound, length);
}
return true;
}
void PerEncoder::encodeBits(char value, unsigned char length) {
// if there are 8 bits available in the last byte copy the
// value in this byte and set the number of used bits
if (usedBits == 8) {
encodeBytes(&value, 1);
usedBits = length;
return;
// if there are not enough bits in the last byte split the value
} else if (usedBits + length > 8) {
// put the first part in the last byte
this->buffer[this->length - 1] += ((unsigned char)value >> usedBits);
// put the remaining part in the next byte after the buffer is increased
// and set the number of used bits according to this part
unsigned char tmpBits = length - (8 - usedBits);
value = (unsigned char)value << (length - tmpBits);
encodeBytes(&value, 1);
usedBits = tmpBits;
// if the value fits in the last byte put it and increase
// the number of used bits in the last byte
} else {
this->buffer[this->length - 1] += ((unsigned char)value >> usedBits);
usedBits += length;
}
}
void PerEncoder::encodeValue(int64_t value, int64_t size) {
for (int i = size - 1; i >= 0; i--) {
char tmp = (char)(value >> i * 8);
encodeBytes(&tmp, 1);
}
usedBits = 8;
}
bool PerEncoder::encodeAbstractType(const AbstractType& abstractType) {
switch(abstractType.getTag()) {
case INTEGER:
return encodeInteger(static_cast<const IntegerBase&>(abstractType));
......@@ -53,6 +204,7 @@ bool PerEncoder::encodeAbstractType(const AbstractType& abstractType) {
}
bool PerEncoder::encodeOpenType(const OpenType& openType) {
if (!encodeLength(openType.getLength(), 0, INT_MAX))
return false;
......@@ -61,41 +213,8 @@ bool PerEncoder::encodeOpenType(const OpenType& openType) {
return true;
}
bool PerEncoder::encodeConstrainedValue(int64_t lowerBound, int64_t upperBound, int64_t val) {
int64_t range = upperBound - lowerBound + 1;
val -= lowerBound;
int64_t bitCount;
if (range < 2) {
return true;
} else if (range < 256) {
bitCount = countBits(range - 1, 0);
val <<= (8 - bitCount);
encodeBits(val, bitCount);
} else if (range < 65537) {
bitCount = (countBits(range - 1, 0) + 7) / 8;
encodeValue(val, bitCount);
} else {
bitCount = (countBits(val, 0) + 7) / 8;
if (!encodeLength(bitCount, (countBits(lowerBound, 0) + 7) / 8, (countBits(upperBound, 0) + 7) / 8))
return false;
encodeValue(val, bitCount);
}
return true;
}
bool PerEncoder::encodeUnconstrainedValue(int64_t value) {
int64_t bitCount = (countBits(value, 0) + 7) / 8;
if (!encodeLength(bitCount, 0, INT_MAX))
return false;
encodeValue(value, bitCount);
return true;
}
bool PerEncoder::encodeInteger(const IntegerBase& integer) {
bool isExtension = (integer.getValue() > integer.getUpperBound());
if (integer.isExtendable()) {
encodeBits(isExtension << 7, 1);
......@@ -108,6 +227,7 @@ bool PerEncoder::encodeInteger(const IntegerBase& integer) {
}
bool PerEncoder::encodeEnumerated(const EnumeratedBase& enumerated) {
bool isExtension = (enumerated.getValue() > enumerated.getUpperBound());
if (enumerated.isExtendable()) {
encodeBits(isExtension << 7, 1);
......@@ -119,42 +239,8 @@ bool PerEncoder::encodeEnumerated(const EnumeratedBase& enumerated) {
return encodeConstrainedValue(0, enumerated.getUpperBound(), enumerated.getValue());
}
void PerEncoder::encodeSmallBitString(char *val, unsigned char len) {
if (len < 9) {
encodeBits(*val, len);
} else {
encodeBits(*val, 8);
encodeBits(*(val + 1), len - 8);
}
}
//bool PerEncoder::encodeConstrainedBitString(const BitString *bitString) {
// int64_t bytesNr;
//
// if ((bitString.getLowerBound() == bitString.getUpperBound())
// && (bitString.getUpperBound() < 65537)
// && (!bitString.isExtension()) && (bitString.getTag() != UNCONSTRAINED)) {
// if (!bitString.length()) {
// return true;
// } else if (bitString.length() < 17) {
// encodeSmallBitString(bitString.getValue(), bitString.length());
// } else {
// bytesNr = (bitString.length() + 7) / 8;
// encodeBytes(bitString.getValue(), bytesNr);
// usedBits = bytesNr * 8 - bitString.length();
// }
// } else {
// if (!encodeLength(bitString.length(), bitString.getLowerBound(), bitString.getTag() != UNCONSTRAINED ? bitString.getUpperBound() : INT_MAX))
// return false;
//
// bytesNr = (bitString.length() + 7) / 8;
// encodeBytes(bitString.getValue(), bytesNr);
// usedBits = bytesNr * 8 - bitString.length();
// }
// return true;
//}
bool PerEncoder::encodeBitString(const BitStringBase& bitString) {
int64_t bytesNr = 0;
bool isExtension = (bitString.getLength() > bitString.getUpperBound());
if (bitString.isExtendable()) {
......@@ -185,27 +271,8 @@ bool PerEncoder::encodeBitString(const BitStringBase& bitString) {
return true;
}
//bool PerEncoder::encodeConstrainedOctetString(const OctetString *octetString) {
// if ((octetString.getLowerBound() == octetString.getUpperBound())
// && (octetString.getUpperBound() < 65537)
// && (!octetString.isExtension()) && (octetString.getTag() != UNCONSTRAINED)) {
// if (!octetString.length()) {
// return true;
// } else if (octetString.length() < 3) {
// encodeSmallBitString(octetString.getValue(), octetString.length() * 8);
// } else {
// encodeBytes(octetString.getValue(), octetString.length());
// }
// } else {
// if (!encodeLength(octetString.length(), octetString.getLowerBound(), octetString.getTag() != UNCONSTRAINED ? octetString.getUpperBound() : INT_MAX)) {
// return false;
// }
// encodeBytes(octetString.getValue(), octetString.length());
// }
// return true;
//}
bool PerEncoder::encodeOctetString(const OctetStringBase& octetString) {
bool isExtension = (octetString.getLength() > octetString.getUpperBound());
if (octetString.isExtendable()) {
encodeBits(isExtension << 7, 1);
......@@ -233,6 +300,7 @@ bool PerEncoder::encodeOctetString(const OctetStringBase& octetString) {
}
bool PerEncoder::encodeSequence(const Sequence& sequence) {
// TODO add support for extension
if (sequence.isExtendable()) {
char extFlag = 0x00;
char *extFlags = sequence.getExtFlags();
......@@ -277,6 +345,7 @@ bool PerEncoder::encodeSequence(const Sequence& sequence) {
}
bool PerEncoder::encodeSequenceOf(const SequenceOfBase& sequenceOf) {
bool isExtension = (sequenceOf.size() > sequenceOf.getUpperBound());
if (sequenceOf.isExtendable()) {
encodeBits(isExtension << 7, 1);
......@@ -296,7 +365,7 @@ bool PerEncoder::encodeSequenceOf(const SequenceOfBase& sequenceOf) {
}
bool PerEncoder::encodeChoice(const Choice& choice) {
// int64_t index = choice.getChoice();
bool isExtension = (choice.getChoice() > choice.getUpperBound());
if (choice.isExtendable()) {
encodeBits(isExtension << 7, 1);
......@@ -340,92 +409,4 @@ bool PerEncoder::encodePrintableString(const PrintableStringBase& printableStrin
return true;
}
void PerEncoder::print(bool type) {
if (type == BIN) {
// for (int64_t i = 0; i < len; i++) {
// for (short j = 7; j >= 0; j--) {
// if ((data[i] & (1 << j)) == 0)
// printf("0");
// else
// printf("1");
// }
// printf(" ");
// }
} else {
char buf[len * 3 + 1];
int j = 0;
for (int i = 0; i < len; i++, j += 3)
sprintf(&buf[j], " %02x ", (unsigned char)val[i]);
buf[len * 3] = '\0';
EV << buf;
}
EV << endl;
}
void PerEncoder::encodeBytes(const char *val, int64_t len) {
this->val = (char *)realloc(this->val, this->len + len);
memcpy(this->val + this->len, val, len);
this->len += len;
usedBits = 8;
}
bool PerEncoder::encodeSmallNumber(int64_t val) {
if (val < 64) {
val = val << 1;
encodeBits((unsigned char )val, 7);
} else {
encodeBits(128, 1);
if (encodeLength(val, 0, INT_MAX) < 0)
return false;
}
return true;
}
bool PerEncoder::encodeLength(int64_t len, int64_t lowerBound, int64_t upperBound) {
if (upperBound > 65535) { /* FIXME */
if (len < 128) {
encodeValue(len, 1);
} else if (len < 16384) {
len += 32768;
encodeValue(len, 2);
} else {
for (unsigned char f = 4; f > 0; f--) {
while((len - f * 16384) >= 0) {
len -= f * 16384;
char tmp = (char )(192 + f);
encodeBytes(&tmp, 1);
}
}
encodeLength(len, lowerBound, upperBound);
}
} else {
return encodeConstrainedValue(lowerBound, upperBound, len);
}
return true;
}
void PerEncoder::encodeBits(char val, unsigned char len) {
if (usedBits == 8) {
encodeBytes(&val, 1);
usedBits = len;
return;
} else if (usedBits + len > 8) {
this->val[this->len - 1] += ((unsigned char)val >> usedBits);
unsigned char tmpBits = len - (8 - usedBits);
val = (unsigned char)val << (len - tmpBits);
encodeBytes(&val, 1);
usedBits = tmpBits;
} else {
this->val[this->len - 1] += ((unsigned char)val >> usedBits);
usedBits += len;
}
}
void PerEncoder::encodeValue(int64_t value, int64_t size) {
for (int i = size - 1; i >= 0; i--) {
char tmp = (char)(value >> i * 8);
encodeBytes(&tmp, 1);
}
usedBits = 8;
}
//
// Copyright (C) 2012 Calin Cerchez
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
......@@ -25,12 +27,32 @@
#define BIN 0
#define HEX 1
/*
* Class for encoding ASN.1 types. The encoder will produce a buffer according to PER
* rules. It will start with an empty buffer and add bytes to it according to desired
* ASN.1 types, which are to be encoded.
*/
class PerEncoder {
private:
short usedBits;
int64_t length;
char *buffer;
/* Utility methods for encoding */
bool encodeConstrainedValue(int64_t lowerBound, int64_t upperBound, int64_t value);
bool encodeUnconstrainedValue(int64_t value);
void encodeSmallBitString(char *value, unsigned char length);
void encodeBytes(const char *value, int64_t length);
bool encodeSmallNumber(int64_t value);
bool encodeLength(int64_t length, int64_t lowerBound, int64_t upperBound);
void encodeBits(char value, unsigned char length);
void encodeValue(int64_t value, int64_t length);
public:
PerEncoder();
virtual ~PerEncoder();
/* Encoding methods */
bool encodeAbstractType(const AbstractType& abstractType);
bool encodeOpenType(const OpenType& openType);
bool encodeInteger(const IntegerBase& integer);
......@@ -44,29 +66,15 @@ public:
void print(bool type);
char *getValue() { return val; }
char getValueAt(int64_t index) { return val[index]; }
void setValue(char *val) { this->val = val; }
int64_t getLength() { return len; }
void setLength(int64_t len) { this->len = len; }
/* Getter methods */
char *getBuffer() { return buffer; }
char getByteAt(int64_t index) { return buffer[index]; }
int64_t getLength() { return length; }
private:
short usedBits;
int64_t len;
char *val;
// bool encodeExtension(const AbstractType *abstractType);
bool encodeConstrainedValue(int64_t lowerBound, int64_t upperBound, int64_t val);
bool encodeUnconstrainedValue(int64_t val);
void encodeSmallBitString(char *val, unsigned char len);
// bool encodeConstrainedBitString(const BitStringBase *bitString);
// bool encodeConstrainedOctetString(const OctetStringBase *octetString);
void encodeBytes(const char *val, int64_t len);
bool encodeSmallNumber(int64_t val);
bool encodeLength(int64_t len, int64_t lowerBound, int64_t upperBound);
void encodeBits(char val, unsigned char len);
void encodeValue(int64_t val, int64_t len);
/* Setter methods */
void setBuffer(char *buffer) { this->buffer = buffer; }
void setLength(int64_t length) { this->length = length; }
// bool checkFullConstraint(int64_t lowerBound, int64_t upperBound, int64_t val, AbstractType *abstractType);
};
#endif /* PERENCODER_H_ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册