Example #1
0
 public static ECDSASignature decodeFromDER(byte[] bytes) {
   ASN1InputStream decoder = null;
   try {
     decoder = new ASN1InputStream(bytes);
     DLSequence seq = (DLSequence) decoder.readObject();
     if (seq == null) throw new RuntimeException("Reached past end of ASN.1 stream.");
     ASN1Integer r, s;
     try {
       r = (ASN1Integer) seq.getObjectAt(0);
       s = (ASN1Integer) seq.getObjectAt(1);
     } catch (ClassCastException e) {
       throw new IllegalArgumentException(e);
     }
     // OpenSSL deviates from the DER spec by interpreting these values as unsigned, though they
     // should not be
     // Thus, we always use the positive versions. See: http://r6.ca/blog/20111119T211504Z.html
     return new ECDSASignature(r.getPositiveValue(), s.getPositiveValue());
   } catch (IOException e) {
     throw new RuntimeException(e);
   } finally {
     if (decoder != null)
       try {
         decoder.close();
       } catch (IOException x) {
       }
   }
 }
  /**
   * Convert an inline encoded hex string rendition of an ASN.1 object back into its corresponding
   * ASN.1 object.
   *
   * @param str the hex encoded object
   * @param off the index at which the encoding starts
   * @return the decoded object
   */
  protected ASN1Primitive convertHexEncoded(String str, int off) throws IOException {
    str = Strings.toLowerCase(str);
    byte[] data = new byte[(str.length() - off) / 2];
    for (int index = 0; index != data.length; index++) {
      char left = str.charAt((index * 2) + off);
      char right = str.charAt((index * 2) + off + 1);

      if (left < 'a') {
        data[index] = (byte) ((left - '0') << 4);
      } else {
        data[index] = (byte) ((left - 'a' + 10) << 4);
      }
      if (right < 'a') {
        data[index] |= (byte) (right - '0');
      } else {
        data[index] |= (byte) (right - 'a' + 10);
      }
    }

    ASN1InputStream aIn = new ASN1InputStream(data);

    return aIn.readObject();
  }