derencoder.java
来自「JAVA的加密库之一」· Java 代码 · 共 525 行 · 第 1/2 页
JAVA
525 行
cat.debug("<== encodeOctetString()");
}
public void encodeUTCTime(IType obj, Date val) throws IOException {
cat.debug("==> encodeUTCTime()");
Tag tag = obj.tag();
cat.info(" tag=\""+tag+"\"");
cat.info(" val="+String.valueOf(val));
SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
byte[] ba = sdf.format(val).getBytes();
if (tag.isExplicit() && !tag.isUniversal())
ba = toTLV(Tag.UTC_TIME, ba);
synchronized (out) {
encode(tag);
encode(ba.length); // write the length
write(ba); // and finally the object's data
flush();
}
cat.debug("<== encodeUTCTime()");
}
public void encodeGeneralizedTime(IType obj, Date val) throws IOException {
cat.debug("==> encodeGeneralizedTime()");
Tag tag = obj.tag();
cat.info(" tag=\""+tag+"\"");
cat.info(" val="+String.valueOf(val));
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss'.'SSS'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
byte[] ba = sdf.format(val).getBytes();
if (tag.isExplicit() && !tag.isUniversal())
ba = toTLV(Tag.GENERALIZED_TIME, ba);
synchronized (out) {
encode(tag);
encode(ba.length); // write the length
write(ba); // and finally the object's data
flush();
}
cat.debug("<== encodeGeneralizedTime()");
}
public void encodeStructure(IIterativeType obj) throws IOException {
cat.debug("==> encodeStructure()");
Tag tag = obj.tag();
cat.info(" tag=\""+tag+"\"");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ASNWriter local = (ASNWriter) this.clone();
local.open(baos);
Object element;
IType t;
ArrayList al;
for (Iterator it = obj.iterator(); it.hasNext(); ) {
element = it.next();
if (element instanceof IType) {
t = (Type) element;
cat.info("Encoding (simple) "+t.getClass().getName()+"...");
t.encode(local);
} else // SEQUENCE/SET OF
for (Iterator ali = ((ArrayList) element).iterator(); ali.hasNext(); ) {
t = (Type) ali.next();
cat.info("Encoding (compound) "+t.getClass().getName()+"...");
t.encode(local);
}
}
local.close();
byte[] ba = baos.toByteArray();
if (tag.isExplicit() && !tag.isUniversal())
ba = toTLV(Tag.SEQUENCE, ba);
synchronized (out) {
encode(tag);
encode(ba.length); // write the length
write(ba); // and finally the object's data
flush();
}
cat.debug("<== encodeStructure()");
}
// OutputStream methods implementation
// .......................................................................
/**
* Writes the specified byte to this output stream. The general contract for
* <tt>write()</tt> is that one byte is written to the output stream. The
* byte to be written is the eight low-order bits of the argument <tt>b</tt>.
* The 24 high-order bits of <tt?b</tt> are ignored.
*
* @param b the <tt>byte</tt>.
* @exception IOException if an I/O error occurs. In particular, an
* <tt>IOException</tt> may be thrown if the output stream has been closed.
*/
public void write(int b) throws IOException {
out.write(b & 0xFF);
}
/**
* Closes the underlying output stream and releases any system resources
* associated with it.
*
* @exception IOException if an I/O error occurs.
*/
public void close() throws IOException {
if (out != null) {
try {
out.close();
} catch (IOException ignored) {
cat.warn("I/O exception while closing the stream: "+ignored.getMessage());
}
out = null;
}
}
/**
* Flushes this output stream and forces any buffered output bytes to be
* written out. The general contract of <tt>flush()</tt> is that calling it is
* an indication that, if any bytes previously written have been buffered by
* the implementation of the output stream, such bytes should immediately be
* written to their intended destination.
*
* @exception IOException if an I/O error occurs.
*/
public void flush() throws IOException {
out.flush();
}
// Tag-related methods
// .......................................................................
/**
* Outputs the current value of this <tt>Tag</tt> instance to the
* designated output stream.
*
* @param tag the Tag instance.
* @exception IOException if an exception occurs while executing this method.
*/
private void encode(Tag tag) throws IOException {
int t = tag.getClazz();
if (tag.isConstructed())
t |= 0x20;
int value = tag.getValue();
if (value < 0x1F)
write(t | value);
else {
write(t | 0x1F);
t = value;
while (t > 63) {
write(63);
t -= 63;
}
write(t);
}
}
// Length-related methods
// .......................................................................
/**
* Encodes the length element of a DER triplet.
*
* @param length the size in bytes of a DER value.
* @exception IOException if an exception occurs while executing this method.
*/
private void encode(int length) throws IOException {
if (length < 128) { // short definite form
write(length);
return;
}
if (length < 256) { // long definite form
write(-127);
write(length);
return;
}
if (length < 65536) {
write(-126);
write(length >> 8);
write(length);
return;
}
if (length < 16777216) {
write(-125);
write(length >> 16);
write(length >> 8);
write(length);
return;
}
write(-124);
write(length >> 24);
write(length >> 16);
write(length >> 8);
write(length);
}
// Other instance methods
// .......................................................................
/**
* Convenience method.<p>
*
* Returns the byte array containing the proper encoding of the designated
* byte array as if tagged by the designated UNIVERSAL class value.
*
* @param universalValue a UNIVERSAL class value to use for tagging.
* @param ba the raw data of an object to encode.
* @return the proper TLV (DER triplet) encoding.
* @exception IOException if an exception occurs while executing this method.
*/
private byte[] toTLV(int universalValue, byte[] ba) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DerEncoder local = new DerEncoder();
local.open(baos);
local.encode(new Tag(universalValue));
local.encode(ba.length);
local.write(ba);
local.close();
return (baos.toByteArray());
}
/**
* Encodes OID subidentifier(s) on 7 bits + 1 bit indicating if last byte or
* not.<p>
*
* <b>BEWARE:</b> This assumes definite length encoding; ie. it will not work
* if value is too big and needs more than 4 bytes to be encoded.
*
* @param baos output stream to write encoding to.
* @param c if this represents the first 2 subidentifiers, enter value as
* first * 40 + second, otherwise just call with subidentifier's value.
* @throws IOException in case we have problems outputting to stream.
*/
private void encodeSubIdentifier(OutputStream os, int c)
throws IOException {
cat.debug("==> encodeSubIdentifier(os, "+String.valueOf(c)+")");
int i = 0;
byte[] ab = new byte[4];
for ( ; i < 4; i++){
ab[i] = (byte)(c & 0x7F);
c >>>= 7;
if (c == 0)
break;
}
// all bytes, except last one have 8th bit set to 1
for ( ; i > 0; i--)
os.write((ab[i] | 0x80) & 0xFF);
os.write(ab[0] & 0xFF);
cat.debug("<== encodeSubIdentifier()");
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?