/** create a private key from the given public key info object. */
  static PrivateKey createPrivateKeyFromPrivateKeyInfo(PrivateKeyInfo info) {
    DERObjectIdentifier algOid = info.getAlgorithmId().getObjectId();

    if (RSAUtil.isRsaOid(algOid)) {
      return new JCERSAPrivateCrtKey(info);
    } else if (algOid.equals(PKCSObjectIdentifiers.dhKeyAgreement)) {
      return new JCEDHPrivateKey(info);
    }
    // BEGIN android-removed
    // else if (algOid.equals(OIWObjectIdentifiers.elGamalAlgorithm))
    // {
    //       return new JCEElGamalPrivateKey(info);
    // }
    // END android-removed
    else if (algOid.equals(X9ObjectIdentifiers.id_dsa)) {
      return new JDKDSAPrivateKey(info);
    }
    // BEGIN android-removed
    // else if (algOid.equals(X9ObjectIdentifiers.id_ecPublicKey))
    // {
    //       return new JCEECPrivateKey(info);
    // }
    // else if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_94))
    // {
    //       return new JDKGOST3410PrivateKey(info);
    // }
    // else if (algOid.equals(CryptoProObjectIdentifiers.gostR3410_2001))
    // {
    //       return new JCEECPrivateKey(info);
    // }
    // END android-removed
    else {
      throw new RuntimeException("algorithm identifier " + algOid + " in key not recognised");
    }
  }
  /**
   * Apply default coversion for the given value depending on the oid and the character range of the
   * value.
   *
   * @param oid the object identifier for the DN entry
   * @param value the value associated with it
   * @return the ASN.1 equivalent for the string value.
   */
  public DERObject getConvertedValue(DERObjectIdentifier oid, String value) {
    if (value.length() != 0 && value.charAt(0) == '#') {
      try {
        return convertHexEncoded(value, 1);
      } catch (IOException e) {
        throw new RuntimeException("can't recode value for oid " + oid.getId());
      }
    } else {
      if (value.length() != 0 && value.charAt(0) == '\\') {
        value = value.substring(1);
      }
      if (oid.equals(X509Name.EmailAddress) || oid.equals(X509Name.DC)) {
        return new DERIA5String(value);
      } else if (oid.equals(
          X509Name.DATE_OF_BIRTH)) // accept time string as well as # (for compatibility)
      {
        return new DERGeneralizedTime(value);
      } else if (oid.equals(X509Name.C)
          || oid.equals(X509Name.SN)
          || oid.equals(X509Name.DN_QUALIFIER)
          || oid.equals(X509Name.TELEPHONE_NUMBER)) {
        return new DERPrintableString(value);
      }
    }

    return new DERUTF8String(value);
  }
Example #3
0
  /**
   * @param inOrder if true the order of both X509 names must be the same, as well as the values
   *     associated with each element.
   */
  public boolean equals(Object obj, boolean inOrder) {
    if (!inOrder) {
      return this.equals(obj);
    }

    if (obj == this) {
      return true;
    }

    if (!(obj instanceof X509Name || obj instanceof ASN1Sequence)) {
      return false;
    }

    DERObject derO = ((DEREncodable) obj).getDERObject();

    if (this.getDERObject().equals(derO)) {
      return true;
    }

    X509Name other;

    try {
      other = X509Name.getInstance(obj);
    } catch (IllegalArgumentException e) {
      return false;
    }

    int orderingSize = ordering.size();

    if (orderingSize != other.ordering.size()) {
      return false;
    }

    for (int i = 0; i < orderingSize; i++) {
      DERObjectIdentifier oid = (DERObjectIdentifier) ordering.elementAt(i);
      DERObjectIdentifier oOid = (DERObjectIdentifier) other.ordering.elementAt(i);

      if (oid.equals(oOid)) {
        String value = (String) values.elementAt(i);
        String oValue = (String) other.values.elementAt(i);

        if (!equivalentStrings(value, oValue)) {
          return false;
        }
      } else {
        return false;
      }
    }

    return true;
  }
 private static boolean certHasPolicy(X509Certificate cert, String sOid) {
   try {
     if (m_logger.isDebugEnabled())
       m_logger.debug("Read cert policies: " + cert.getSerialNumber().toString());
     ByteArrayInputStream bIn = new ByteArrayInputStream(cert.getEncoded());
     ASN1InputStream aIn = new ASN1InputStream(bIn);
     ASN1Sequence seq = (ASN1Sequence) aIn.readObject();
     X509CertificateStructure obj = new X509CertificateStructure(seq);
     TBSCertificateStructure tbsCert = obj.getTBSCertificate();
     if (tbsCert.getVersion() == 3) {
       X509Extensions ext = tbsCert.getExtensions();
       if (ext != null) {
         Enumeration en = ext.oids();
         while (en.hasMoreElements()) {
           DERObjectIdentifier oid = (DERObjectIdentifier) en.nextElement();
           X509Extension extVal = ext.getExtension(oid);
           ASN1OctetString oct = extVal.getValue();
           ASN1InputStream extIn = new ASN1InputStream(new ByteArrayInputStream(oct.getOctets()));
           // if (oid.equals(X509Extensions.CertificatePolicies)) { // bc 146 ja jdk 1.6 puhul -
           // X509Extension.certificatePolicies
           if (oid.equals(X509Extension.certificatePolicies)) { // bc 146 ja jdk 1.6 puhul -
             // X509Extension.certificatePolicies
             ASN1Sequence cp = (ASN1Sequence) extIn.readObject();
             for (int i = 0; i != cp.size(); i++) {
               PolicyInformation pol = PolicyInformation.getInstance(cp.getObjectAt(i));
               DERObjectIdentifier dOid = pol.getPolicyIdentifier();
               String soid2 = dOid.getId();
               if (m_logger.isDebugEnabled()) m_logger.debug("Policy: " + soid2);
               if (soid2.startsWith(sOid)) return true;
             }
           }
         }
       }
     }
   } catch (Exception ex) {
     m_logger.error("Error reading cert policies: " + ex);
   }
   return false;
 }
  private boolean doVerify(SignerInformationVerifier verifier) throws CMSException {
    String digestName = CMSSignedHelper.INSTANCE.getDigestAlgName(this.getDigestAlgOID());
    String encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID());
    String signatureName = digestName + "with" + encName;

    try {
      if (digestCalculator != null) {
        resultDigest = digestCalculator.getDigest();
      } else {
        DigestCalculator calc = verifier.getDigestCalculator(this.getDigestAlgorithmID());
        if (content != null) {
          OutputStream digOut = calc.getOutputStream();

          content.write(digOut);

          digOut.close();
        } else if (signedAttributeSet == null) {
          // TODO Get rid of this exception and just treat content==null as empty not missing?
          throw new CMSException("data not encapsulated in signature - use detached constructor.");
        }

        resultDigest = calc.getDigest();
      }
    } catch (IOException e) {
      throw new CMSException("can't process mime object to create signature.", e);
    } catch (NoSuchAlgorithmException e) {
      throw new CMSException("can't find algorithm: " + e.getMessage(), e);
    } catch (OperatorCreationException e) {
      throw new CMSException("can't create digest calculator: " + e.getMessage(), e);
    }

    // RFC 3852 11.1 Check the content-type attribute is correct
    {
      DERObject validContentType =
          getSingleValuedSignedAttribute(CMSAttributes.contentType, "content-type");
      if (validContentType == null) {
        if (!isCounterSignature && signedAttributeSet != null) {
          throw new CMSException(
              "The content-type attribute type MUST be present whenever signed attributes are present in signed-data");
        }
      } else {
        if (isCounterSignature) {
          throw new CMSException(
              "[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute");
        }

        if (!(validContentType instanceof DERObjectIdentifier)) {
          throw new CMSException(
              "content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'");
        }

        DERObjectIdentifier signedContentType = (DERObjectIdentifier) validContentType;

        if (!signedContentType.equals(contentType)) {
          throw new CMSException("content-type attribute value does not match eContentType");
        }
      }
    }

    // RFC 3852 11.2 Check the message-digest attribute is correct
    {
      DERObject validMessageDigest =
          getSingleValuedSignedAttribute(CMSAttributes.messageDigest, "message-digest");
      if (validMessageDigest == null) {
        if (signedAttributeSet != null) {
          throw new CMSException(
              "the message-digest signed attribute type MUST be present when there are any signed attributes present");
        }
      } else {
        if (!(validMessageDigest instanceof ASN1OctetString)) {
          throw new CMSException("message-digest attribute value not of ASN.1 type 'OCTET STRING'");
        }

        ASN1OctetString signedMessageDigest = (ASN1OctetString) validMessageDigest;

        if (!Arrays.constantTimeAreEqual(resultDigest, signedMessageDigest.getOctets())) {
          throw new CMSSignerDigestMismatchException(
              "message-digest attribute value does not match calculated value");
        }
      }
    }

    // RFC 3852 11.4 Validate countersignature attribute(s)
    {
      AttributeTable signedAttrTable = this.getSignedAttributes();
      if (signedAttrTable != null
          && signedAttrTable.getAll(CMSAttributes.counterSignature).size() > 0) {
        throw new CMSException("A countersignature attribute MUST NOT be a signed attribute");
      }

      AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
      if (unsignedAttrTable != null) {
        ASN1EncodableVector csAttrs = unsignedAttrTable.getAll(CMSAttributes.counterSignature);
        for (int i = 0; i < csAttrs.size(); ++i) {
          Attribute csAttr = (Attribute) csAttrs.get(i);
          if (csAttr.getAttrValues().size() < 1) {
            throw new CMSException(
                "A countersignature attribute MUST contain at least one AttributeValue");
          }

          // Note: We don't recursively validate the countersignature value
        }
      }
    }

    try {
      ContentVerifier contentVerifier =
          verifier.getContentVerifier(sigAlgFinder.find(signatureName));
      OutputStream sigOut = contentVerifier.getOutputStream();

      if (signedAttributeSet == null) {
        if (digestCalculator != null) {
          if (contentVerifier instanceof RawContentVerifier) {
            RawContentVerifier rawVerifier = (RawContentVerifier) contentVerifier;

            if (encName.equals("RSA")) {
              DigestInfo digInfo = new DigestInfo(digestAlgorithm, resultDigest);

              return rawVerifier.verify(digInfo.getDEREncoded(), this.getSignature());
            }

            return rawVerifier.verify(resultDigest, this.getSignature());
          }

          throw new CMSException("verifier unable to process raw signature");
        } else if (content != null) {
          // TODO Use raw signature of the hash value instead
          content.write(sigOut);
        }
      } else {
        sigOut.write(this.getEncodedSignedAttributes());
      }

      sigOut.close();

      return contentVerifier.verify(this.getSignature());
    } catch (IOException e) {
      throw new CMSException("can't process mime object to create signature.", e);
    } catch (OperatorCreationException e) {
      throw new CMSException("can't create content verifier: " + e.getMessage(), e);
    }
  }
  /** @deprecated */
  private boolean doVerify(PublicKey key, Provider sigProvider)
      throws CMSException, NoSuchAlgorithmException {
    String digestName = CMSSignedHelper.INSTANCE.getDigestAlgName(this.getDigestAlgOID());
    String encName = CMSSignedHelper.INSTANCE.getEncryptionAlgName(this.getEncryptionAlgOID());
    String signatureName = digestName + "with" + encName;
    Signature sig = CMSSignedHelper.INSTANCE.getSignatureInstance(signatureName, sigProvider);
    MessageDigest digest = CMSSignedHelper.INSTANCE.getDigestInstance(digestName, sigProvider);

    // TODO [BJA-109] Note: PSSParameterSpec requires JDK1.4+
    /*
            try
            {
                DERObjectIdentifier sigAlgOID = encryptionAlgorithm.getObjectId();
                DEREncodable sigParams = this.encryptionAlgorithm.getParameters();
                if (sigAlgOID.equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
                {
                    // RFC 4056
                    // When the id-RSASSA-PSS algorithm identifier is used for a signature,
                    // the AlgorithmIdentifier parameters field MUST contain RSASSA-PSS-params.
                    if (sigParams == null)
                    {
                        throw new CMSException(
                            "RSASSA-PSS signature must specify algorithm parameters");
                    }

                    AlgorithmParameters params = AlgorithmParameters.getInstance(
                        sigAlgOID.getId(), sig.getProvider().getName());
                    params.init(sigParams.getDERObject().getEncoded(), "ASN.1");

                    PSSParameterSpec spec = (PSSParameterSpec)params.getParameterSpec(PSSParameterSpec.class);
                    sig.setParameter(spec);
                }
                else
                {
                    // TODO Are there other signature algorithms that provide parameters?
                    if (sigParams != null)
                    {
                        throw new CMSException("unrecognised signature parameters provided");
                    }
                }
            }
            catch (IOException e)
            {
                throw new CMSException("error encoding signature parameters.", e);
            }
            catch (InvalidAlgorithmParameterException e)
            {
                throw new CMSException("error setting signature parameters.", e);
            }
            catch (InvalidParameterSpecException e)
            {
                throw new CMSException("error processing signature parameters.", e);
            }
    */

    try {
      if (digestCalculator != null) {
        resultDigest = digestCalculator.getDigest();
      } else {
        if (content != null) {
          content.write(new DigOutputStream(digest));
        } else if (signedAttributeSet == null) {
          // TODO Get rid of this exception and just treat content==null as empty not missing?
          throw new CMSException("data not encapsulated in signature - use detached constructor.");
        }

        resultDigest = digest.digest();
      }
    } catch (IOException e) {
      throw new CMSException("can't process mime object to create signature.", e);
    }

    // RFC 3852 11.1 Check the content-type attribute is correct
    {
      DERObject validContentType =
          getSingleValuedSignedAttribute(CMSAttributes.contentType, "content-type");
      if (validContentType == null) {
        if (!isCounterSignature && signedAttributeSet != null) {
          throw new CMSException(
              "The content-type attribute type MUST be present whenever signed attributes are present in signed-data");
        }
      } else {
        if (isCounterSignature) {
          throw new CMSException(
              "[For counter signatures,] the signedAttributes field MUST NOT contain a content-type attribute");
        }

        if (!(validContentType instanceof DERObjectIdentifier)) {
          throw new CMSException(
              "content-type attribute value not of ASN.1 type 'OBJECT IDENTIFIER'");
        }

        DERObjectIdentifier signedContentType = (DERObjectIdentifier) validContentType;

        if (!signedContentType.equals(contentType)) {
          throw new CMSException("content-type attribute value does not match eContentType");
        }
      }
    }

    // RFC 3852 11.2 Check the message-digest attribute is correct
    {
      DERObject validMessageDigest =
          getSingleValuedSignedAttribute(CMSAttributes.messageDigest, "message-digest");
      if (validMessageDigest == null) {
        if (signedAttributeSet != null) {
          throw new CMSException(
              "the message-digest signed attribute type MUST be present when there are any signed attributes present");
        }
      } else {
        if (!(validMessageDigest instanceof ASN1OctetString)) {
          throw new CMSException("message-digest attribute value not of ASN.1 type 'OCTET STRING'");
        }

        ASN1OctetString signedMessageDigest = (ASN1OctetString) validMessageDigest;

        if (!Arrays.constantTimeAreEqual(resultDigest, signedMessageDigest.getOctets())) {
          throw new CMSSignerDigestMismatchException(
              "message-digest attribute value does not match calculated value");
        }
      }
    }

    // RFC 3852 11.4 Validate countersignature attribute(s)
    {
      AttributeTable signedAttrTable = this.getSignedAttributes();
      if (signedAttrTable != null
          && signedAttrTable.getAll(CMSAttributes.counterSignature).size() > 0) {
        throw new CMSException("A countersignature attribute MUST NOT be a signed attribute");
      }

      AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
      if (unsignedAttrTable != null) {
        ASN1EncodableVector csAttrs = unsignedAttrTable.getAll(CMSAttributes.counterSignature);
        for (int i = 0; i < csAttrs.size(); ++i) {
          Attribute csAttr = (Attribute) csAttrs.get(i);
          if (csAttr.getAttrValues().size() < 1) {
            throw new CMSException(
                "A countersignature attribute MUST contain at least one AttributeValue");
          }

          // Note: We don't recursively validate the countersignature value
        }
      }
    }

    try {
      sig.initVerify(key);

      if (signedAttributeSet == null) {
        if (digestCalculator != null) {
          // need to decrypt signature and check message bytes
          return verifyDigest(resultDigest, key, this.getSignature(), sigProvider);
        } else if (content != null) {
          // TODO Use raw signature of the hash value instead
          content.write(new SigOutputStream(sig));
        }
      } else {
        sig.update(this.getEncodedSignedAttributes());
      }

      return sig.verify(this.getSignature());
    } catch (InvalidKeyException e) {
      throw new CMSException("key not appropriate to signature in message.", e);
    } catch (IOException e) {
      throw new CMSException("can't process mime object to create signature.", e);
    } catch (SignatureException e) {
      throw new CMSException("invalid signature format in message: " + e.getMessage(), e);
    }
  }
Example #7
0
  /** test for equality - note: case is ignored. */
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }

    if (!(obj instanceof X509Name || obj instanceof ASN1Sequence)) {
      return false;
    }

    DERObject derO = ((DEREncodable) obj).getDERObject();

    if (this.getDERObject().equals(derO)) {
      return true;
    }

    X509Name other;

    try {
      other = X509Name.getInstance(obj);
    } catch (IllegalArgumentException e) {
      return false;
    }

    int orderingSize = ordering.size();

    if (orderingSize != other.ordering.size()) {
      return false;
    }

    boolean[] indexes = new boolean[orderingSize];
    int start, end, delta;

    if (ordering.elementAt(0).equals(other.ordering.elementAt(0))) // guess forward
    {
      start = 0;
      end = orderingSize;
      delta = 1;
    } else // guess reversed - most common problem
    {
      start = orderingSize - 1;
      end = -1;
      delta = -1;
    }

    for (int i = start; i != end; i += delta) {
      boolean found = false;
      DERObjectIdentifier oid = (DERObjectIdentifier) ordering.elementAt(i);
      String value = (String) values.elementAt(i);

      for (int j = 0; j < orderingSize; j++) {
        if (indexes[j]) {
          continue;
        }

        DERObjectIdentifier oOid = (DERObjectIdentifier) other.ordering.elementAt(j);

        if (oid.equals(oOid)) {
          String oValue = (String) other.values.elementAt(j);

          if (equivalentStrings(value, oValue)) {
            indexes[j] = true;
            found = true;
            break;
          }
        }
      }

      if (!found) {
        return false;
      }
    }

    return true;
  }