8 * Copyright (C) 2009 Adam Kropelin
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of version 2 of the GNU General
12 * Public License as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
31 void debug(const char *foo
, int indent
)
38 // *****************************************************************************
40 // *****************************************************************************
42 Object
*Object::Demarshal(unsigned char *&buffer
, unsigned int &buflen
)
44 static int indent
= 0;
46 // Must have at least one byte to work with
50 // Extract type code from stream
51 Identifier type
= (Identifier
)*buffer
++;
54 // Create proper object based on type code
63 debug("INTEGER", indent
);
64 obj
= new Integer(type
);
68 debug("OCTETSTRING", indent
);
69 obj
= new OctetString();
72 debug("OBJECTID", indent
);
76 debug("NULLL", indent
);
84 debug("SEQUENCE", indent
);
86 obj
= new Sequence(type
);
89 printf("UNKNOWN ASN type=0x%02x\n", type
);
90 debug("UNKNOWN", indent
);
95 // Have the object demarshal itself from the stream
96 if (obj
&& !obj
->demarshal(buffer
, buflen
))
102 if (type
& CONSTRUCTED
)
108 int Object::numbits(unsigned int num
) const
123 bool Object::marshalLength(
125 unsigned char *&buffer
,
126 unsigned int &buflen
) const
128 // Compute number of bytes required to store length
129 unsigned int bits
= numbits(len
);
130 unsigned int datalen
;
134 datalen
= (bits
+ 7) / 8 + 1;
136 // If no buffer provided, just return number of bytes required
143 // Fail if not enough space remaining in buffer
144 if (buflen
< datalen
)
147 // If using long form, begin with byte count
149 *buffer
++ = (datalen
- 1) | 0x80;
151 // Encode length bytes
155 *buffer
++ = (len
>> 24) & 0xff;
157 *buffer
++ = (len
>> 16) & 0xff;
159 *buffer
++ = (len
>> 8) & 0xff;
162 *buffer
++ = len
& 0xff;
169 bool Object::marshalType(unsigned char *&buffer
, unsigned int &buflen
) const
171 // If no buffer provided, just return number of bytes required
178 // Fail if not enough room for data
183 // Store type directly in stream
188 bool Object::demarshalLength(
189 unsigned char *&buffer
,
190 unsigned int &buflen
,
191 unsigned int &vallen
) const
193 // Must have at least one byte to work with
196 unsigned int datalen
= *buffer
++;
199 // Values less than 128 are stored directly in the first (only) byte
206 // For values > 128, first byte-128 indicates number of bytes to follow
207 // Bail if not enough data for additional bytes
209 if (buflen
< datalen
)
224 // *****************************************************************************
226 // *****************************************************************************
228 bool Integer::Marshal(unsigned char *&buffer
, unsigned int &buflen
) const
230 // Marshal the type code
231 if (!marshalType(buffer
, buflen
))
234 // Calculate the number of bytes it will require to store the value
235 unsigned int datalen
= 4;
236 unsigned int tmp
= _value
;
239 if (( _signed
&& (tmp
& 0xff800000) != 0xff800000) ||
240 (!_signed
&& (tmp
& 0xff800000) != 0x00000000))
247 // Special case for unsigned value with MSb set
248 if (!_signed
&& datalen
== 4 && (tmp
& 0x80000000))
251 // Marshal the length
252 if (!marshalLength(datalen
, buffer
, buflen
))
255 // If no buffer provided, just return number of bytes required
262 // Fail if not enough room for data
263 if (buflen
< datalen
)
267 // Marshal the value itself
273 *buffer
++ = (_value
>> 24) & 0xff;
275 *buffer
++ = (_value
>> 16) & 0xff;
277 *buffer
++ = (_value
>> 8) & 0xff;
279 *buffer
++ = _value
& 0xff;
285 bool Integer::demarshal(unsigned char *&buffer
, unsigned int &buflen
)
287 // Unmarshal the data length
288 unsigned int datalen
;
289 if (!demarshalLength(buffer
, buflen
, datalen
) ||
290 datalen
< 1 || datalen
> 4 || buflen
< datalen
)
296 // Determine signedness
299 // Start with all 1s so result will be sign-extended
300 _value
= (unsigned int)-1;
309 // Unmarshal the data
319 // *****************************************************************************
321 // *****************************************************************************
323 OctetString::OctetString(const char *value
) :
327 assign((const unsigned char *)value
, strlen(value
));
330 OctetString::OctetString(const unsigned char *value
, unsigned int len
) :
337 OctetString::OctetString(const OctetString
&rhs
) :
341 assign(rhs
._data
, rhs
._len
);
344 OctetString
&OctetString::operator=(const OctetString
&rhs
)
347 assign(rhs
._data
, rhs
._len
);
351 bool OctetString::Marshal(unsigned char *&buffer
, unsigned int &buflen
) const
353 // Marshal the type code
354 if (!marshalType(buffer
, buflen
))
357 // Marshal the length
358 if (!marshalLength(_len
, buffer
, buflen
))
361 // If no buffer provided, just return number of bytes required
368 // Bail if not enough room for data
369 if ((unsigned int)buflen
< _len
)
374 memcpy(buffer
, _data
, _len
);
380 bool OctetString::demarshal(unsigned char *&buffer
, unsigned int &buflen
)
382 // Unmarshal the data length
383 unsigned int datalen
;
384 if (!demarshalLength(buffer
, buflen
, datalen
) ||
385 datalen
< 1 || buflen
< datalen
)
391 // Unmarshal the data
392 assign(buffer
, datalen
);
398 void OctetString::assign(const unsigned char *data
, unsigned int len
)
401 _data
= new unsigned char[len
+1];
402 memcpy(_data
, data
, len
);
407 // *****************************************************************************
409 // *****************************************************************************
411 ObjectId::ObjectId(const int oid
[]) :
418 ObjectId::ObjectId(const ObjectId
&rhs
) :
422 assign(rhs
._value
, rhs
._count
);
425 ObjectId
&ObjectId::operator=(const ObjectId
&rhs
)
428 assign(rhs
._value
, rhs
._count
);
432 ObjectId
&ObjectId::operator=(const int oid
[])
439 void ObjectId::assign(const int oid
[])
441 unsigned int count
= 0;
442 while (oid
[count
] != -1)
447 void ObjectId::assign(const int oid
[], unsigned int count
)
454 _value
= new int[_count
];
455 memcpy(_value
, oid
, _count
*sizeof(int));
459 bool ObjectId::operator==(const ObjectId
&rhs
) const
461 if (_count
!= rhs
._count
)
464 for (unsigned int i
= 0; i
< _count
; i
++)
466 if (_value
[i
] != rhs
._value
[i
])
473 bool ObjectId::operator==(const int oid
[]) const
476 for (i
= 0; i
< _count
&& oid
[i
] != -1; i
++)
478 if (_value
[i
] != oid
[i
])
482 return i
== _count
&& oid
[i
] == -1;
485 // Same as operator== except we're allowed to be longer than the parameter
486 bool ObjectId::IsChildOf(const int oid
[])
489 for (i
= 0; i
< _count
&& oid
[i
] != -1; i
++)
491 if (_value
[i
] != oid
[i
])
495 return i
< _count
&& oid
[i
] == -1;
498 bool ObjectId::Marshal(unsigned char *&buffer
, unsigned int &buflen
) const
500 // Protect from trying to marshal an empty object
501 if (!_value
|| _count
< 2)
504 // Marshal the type code
505 if (!marshalType(buffer
, buflen
))
508 // ASN.1 requires a special case for first two identifiers
509 unsigned int cnt
= _count
-1;
510 unsigned int vals
[cnt
];
511 vals
[0] = _value
[0] * 40 + _value
[1];
512 for (unsigned int i
= 2; i
< _count
; i
++)
513 vals
[i
-1] = _value
[i
];
515 // Calculate number of octets required to store data
516 // We can only store 7 bits of data in each octet, so round accordingly
517 unsigned int datalen
= 0;
518 for (unsigned int i
= 0; i
< cnt
; i
++)
519 datalen
+= (numbits(vals
[i
]) + 6) / 7;
521 // Marshal the length
522 if (!marshalLength(datalen
, buffer
, buflen
))
525 // If no buffer provided, just return number of bytes required
532 // Bail if data bytes will not fit
533 if (buflen
< datalen
)
537 // Write data: 7 data bits per octet, bit 7 set on all but final octet
538 for (unsigned int i
= 0; i
< cnt
; i
++)
540 unsigned int val
= vals
[i
];
541 unsigned int noctets
= (numbits(val
) + 6) / 7;
545 *buffer
++ = ((val
>> 28) & 0x7f) | 0x80;
547 *buffer
++ = ((val
>> 21) & 0x7f) | 0x80;
549 *buffer
++ = ((val
>> 14) & 0x7f) | 0x80;
551 *buffer
++ = ((val
>> 7) & 0x7f) | 0x80;
554 *buffer
++ = val
& 0x7f;
561 bool ObjectId::demarshal(unsigned char *&buffer
, unsigned int &buflen
)
563 // Unmarshal the data length
564 unsigned int datalen
;
565 if (!demarshalLength(buffer
, buflen
, datalen
) ||
566 datalen
< 1 || buflen
< datalen
)
572 // Allocate new value array, sized for worst case. +1 is because of
573 // ASN.1 special case of compressing first two ids into one octet.
575 _value
= new int[datalen
+1];
577 // Unmarshal identifier values
581 // Accumulate octets into this identifier
589 _value
[i
] |= val
& 0x7f;
591 while (datalen
&& val
& 0x80);
593 // Handle special case for first two ids
596 _value
[1] = _value
[0] % 40;
606 // *****************************************************************************
608 // *****************************************************************************
610 bool Null::Marshal(unsigned char *&buffer
, unsigned int &buflen
) const
612 // Marshal the type code
613 if (!marshalType(buffer
, buflen
))
616 // Marshal the length
617 if (!marshalLength(0, buffer
, buflen
))
623 bool Null::demarshal(unsigned char *&buffer
, unsigned int &buflen
)
625 // Unmarshal the data length
626 unsigned int datalen
;
627 return demarshalLength(buffer
, buflen
, datalen
) && datalen
== 0;
630 // *****************************************************************************
632 // *****************************************************************************
634 Sequence::Sequence(Identifier type
) :
641 Sequence::~Sequence()
646 Sequence::Sequence(const Sequence
&rhs
) :
653 void Sequence::clear()
655 for (unsigned int i
= 0; i
< _size
; i
++)
661 bool Sequence::Marshal(unsigned char *&buffer
, unsigned int &buflen
) const
663 // Marshal the type code
664 if (!marshalType(buffer
, buflen
))
667 // Need to calculate the length of the marshalled sequence.
668 // Do so by passing a NULL buffer to Marshal() which will
669 // accumulate total length in buflen parameter.
670 unsigned int datalen
= 0;
671 unsigned char *buf
= NULL
;
672 for (unsigned int i
= 0; i
< _size
; ++i
)
674 if (!_data
[i
]->Marshal(buf
, datalen
))
678 // Now marshal the length itself
679 if (!marshalLength(datalen
, buffer
, buflen
))
682 // If no buffer provided, just return number of bytes required
689 // Marshal all items in the sequence
690 for (unsigned int i
= 0; i
< _size
; ++i
)
692 if (!_data
[i
]->Marshal(buffer
, buflen
))
699 bool Sequence::demarshal(unsigned char *&buffer
, unsigned int &buflen
)
701 // Free any existing data
704 // Unmarshal the sequence data length
705 unsigned int datalen
;
706 if (!demarshalLength(buffer
, buflen
, datalen
) ||
707 datalen
< 1 || buflen
< datalen
)
712 // Unmarshal items from the stream until sequence data is exhausted
713 unsigned char *start
= buffer
;
716 Object
*obj
= Object::Demarshal(buffer
, datalen
);
722 buflen
-= buffer
-start
;
726 void Sequence::Append(Object
*obj
)
728 // realloc ... not efficient, but easy
729 Object
**tmp
= new Object
*[_size
+1];
730 memcpy(tmp
, _data
, _size
* sizeof(_data
[0]));
736 Object
*Sequence::operator[](unsigned int idx
)
743 Sequence
&Sequence::operator=(const Sequence
&rhs
)
750 void Sequence::assign(const Sequence
&rhs
)
756 _data
= new Object
*[_size
];
758 for (unsigned int i
= 0; i
< _size
; i
++)
759 _data
[i
] = rhs
._data
[i
]->copy();