private String hostNameMessage(X509Certificate cert, String hostname) {
    StringBuffer si = new StringBuffer();

    si.append(master.getString(R.string.mtm_hostname_mismatch, hostname));
    si.append("\n\n");
    try {
      Collection<List<?>> sans = cert.getSubjectAlternativeNames();
      if (sans == null) {
        si.append(cert.getSubjectDN());
        si.append("\n");
      } else
        for (List<?> altName : sans) {
          Object name = altName.get(1);
          if (name instanceof String) {
            si.append("[");
            si.append((Integer) altName.get(0));
            si.append("] ");
            si.append(name);
            si.append("\n");
          }
        }
    } catch (CertificateParsingException e) {
      e.printStackTrace();
      si.append("<Parsing error: ");
      si.append(e.getLocalizedMessage());
      si.append(">\n");
    }
    si.append("\n");
    si.append(master.getString(R.string.mtm_connect_anyway));
    si.append("\n\n");
    si.append(master.getString(R.string.mtm_cert_details));
    certDetails(si, cert);
    return si.toString();
  }
 /**
  * Extracts the array of SubjectAlt DNS names from an X509Certificate. Returns null if there
  * aren't any.
  *
  * <p>Note: Java doesn't appear able to extract international characters from the SubjectAlts. It
  * can only extract international characters from the CN field.
  *
  * <p>(Or maybe the version of OpenSSL I'm using to test isn't storing the international
  * characters correctly in the SubjectAlts?).
  *
  * @param cert X509Certificate
  * @return Array of SubjectALT DNS names stored in the certificate.
  */
 public static String[] getDNSSubjectAlts(X509Certificate cert) {
   LinkedList subjectAltList = new LinkedList();
   Collection c = null;
   try {
     c = cert.getSubjectAlternativeNames();
   } catch (CertificateParsingException cpe) {
     // Should probably log.debug() this?
     cpe.printStackTrace();
   }
   if (c != null) {
     Iterator it = c.iterator();
     while (it.hasNext()) {
       List list = (List) it.next();
       int type = ((Integer) list.get(0)).intValue();
       // If type is 2, then we've got a dNSName
       if (type == 2) {
         String s = (String) list.get(1);
         subjectAltList.add(s);
       }
     }
   }
   if (!subjectAltList.isEmpty()) {
     String[] subjectAlts = new String[subjectAltList.size()];
     subjectAltList.toArray(subjectAlts);
     return subjectAlts;
   } else {
     return null;
   }
 }
  /** Read an existing PKCS#7 object from a DER encoded byte array */
  public PKCS7SignedData(byte[] in, String provider)
      throws SecurityException, CRLException, InvalidKeyException, NoSuchProviderException,
          NoSuchAlgorithmException {
    ASN1InputStream din = new ASN1InputStream(new ByteArrayInputStream(in));

    //
    // Basic checks to make sure it's a PKCS#7 SignedData Object
    //
    DERObject pkcs;

    try {
      pkcs = din.readObject();
    } catch (IOException e) {
      throw new SecurityException("can't decode PKCS7SignedData object");
    }

    if (!(pkcs instanceof ASN1Sequence)) {
      throw new SecurityException("Not a valid PKCS#7 object - not a sequence");
    }

    ContentInfo content = ContentInfo.getInstance(pkcs);

    if (!content.getContentType().equals(signedData)) {
      throw new SecurityException(
          "Not a valid PKCS#7 signed-data object - wrong header "
              + content.getContentType().getId());
    }

    SignedData data = SignedData.getInstance(content.getContent());

    certs = new ArrayList();

    if (data.getCertificates() != null) {
      Enumeration ec = ASN1Set.getInstance(data.getCertificates()).getObjects();

      while (ec.hasMoreElements()) {
        try {
          certs.add(
              new X509CertificateObject(X509CertificateStructure.getInstance(ec.nextElement())));
        } catch (CertificateParsingException e) {
          throw new SecurityException(e.toString());
        }
      }
    }

    crls = new ArrayList();

    if (data.getCRLs() != null) {
      Enumeration ec = ASN1Set.getInstance(data.getCRLs()).getObjects();
      while (ec.hasMoreElements()) {
        crls.add(new X509CRLObject(CertificateList.getInstance(ec.nextElement())));
      }
    }

    version = data.getVersion().getValue().intValue();

    //
    // Get the digest algorithm
    //
    digestalgos = new HashSet();
    Enumeration e = data.getDigestAlgorithms().getObjects();

    while (e.hasMoreElements()) {
      ASN1Sequence s = (ASN1Sequence) e.nextElement();
      DERObjectIdentifier o = (DERObjectIdentifier) s.getObjectAt(0);
      digestalgos.add(o.getId());
    }

    //
    // Get the SignerInfo
    //
    ASN1Set signerinfos = data.getSignerInfos();
    if (signerinfos.size() != 1) {
      throw new SecurityException(
          "This PKCS#7 object has multiple SignerInfos - only one is supported at this time");
    }

    SignerInfo signerInfo = SignerInfo.getInstance(signerinfos.getObjectAt(0));

    signerversion = signerInfo.getVersion().getValue().intValue();

    IssuerAndSerialNumber isAnds = signerInfo.getIssuerAndSerialNumber();

    //
    // Get the signing certificate
    //
    BigInteger serialNumber = isAnds.getCertificateSerialNumber().getValue();
    X509Principal issuer = new X509Principal(isAnds.getName());

    for (Iterator i = certs.iterator(); i.hasNext(); ) {
      X509Certificate cert = (X509Certificate) i.next();
      if (serialNumber.equals(cert.getSerialNumber()) && issuer.equals(cert.getIssuerDN())) {
        signCert = cert;
        break;
      }
    }

    if (signCert == null) {
      throw new SecurityException(
          "Can't find signing certificate with serial " + serialNumber.toString(16));
    }

    digestAlgorithm = signerInfo.getDigestAlgorithm().getObjectId().getId();

    digest = signerInfo.getEncryptedDigest().getOctets();
    digestEncryptionAlgorithm = signerInfo.getDigestEncryptionAlgorithm().getObjectId().getId();

    sig = Signature.getInstance(getDigestAlgorithm(), provider);

    sig.initVerify(signCert.getPublicKey());
  }
Пример #4
0
      } else {
         ContentInfo var19 = ContentInfo.getInstance(var16);
         DERObjectIdentifier var20 = var19.getContentType();
         DERObjectIdentifier var21 = signedData;
         if(!var20.equals(var21)) {
            StringBuilder var22 = (new StringBuilder()).append("Not a valid PKCS#7 signed-data object - wrong header ");
            String var23 = var19.getContentType().getId();
            String var24 = var22.append(var23).toString();
            throw new SecurityException(var24);
         } else {
            SignedData var25 = SignedData.getInstance(var19.getContent());
            ArrayList var26 = new ArrayList();
            this.certs = var26;
            Enumeration var27;
            if(var25.getCertificates() != null) {
               var27 = ASN1Set.getInstance(var25.getCertificates()).getObjects();

               while(var27.hasMoreElements()) {
                  try {
                     Collection var28 = this.certs;
                     X509CertificateStructure var29 = X509CertificateStructure.getInstance(var27.nextElement());
                     X509CertificateObject var30 = new X509CertificateObject(var29);
                     var28.add(var30);
                  } catch (CertificateParsingException var80) {
                     String var32 = var80.toString();
                     throw new SecurityException(var32);
                  }
               }
            }

            ArrayList var33 = new ArrayList();
            this.crls = var33;
            if(var25.getCRLs() != null) {
               var27 = ASN1Set.getInstance(var25.getCRLs()).getObjects();

               while(var27.hasMoreElements()) {
                  Collection var34 = this.crls;
                  CertificateList var35 = CertificateList.getInstance(var27.nextElement());
                  X509CRLObject var36 = new X509CRLObject(var35);
                  var34.add(var36);
               }
            }

            int var38 = var25.getVersion().getValue().intValue();
            this.version = var38;
            HashSet var39 = new HashSet();
            this.digestalgos = var39;
            Enumeration var40 = var25.getDigestAlgorithms().getObjects();

            while(var40.hasMoreElements()) {
               ASN1Sequence var41 = (ASN1Sequence)var40.nextElement();
               byte var42 = 0;
               DERObjectIdentifier var43 = (DERObjectIdentifier)var41.getObjectAt(var42);
               Set var44 = this.digestalgos;
               String var45 = var43.getId();
               var44.add(var45);
            }

            ASN1Set var47 = var25.getSignerInfos();
            int var48 = var47.size();
            byte var49 = 1;
            if(var48 != var49) {
               throw new SecurityException("This PKCS#7 object has multiple SignerInfos - only one is supported at this time");
            } else {
               SignerInfo var50 = SignerInfo.getInstance(var47.getObjectAt(0));
               int var51 = var50.getVersion().getValue().intValue();
               this.signerversion = var51;
               IssuerAndSerialNumber var52 = var50.getIssuerAndSerialNumber();
               BigInteger var53 = var52.getCertificateSerialNumber().getValue();
               X509Principal var54 = new X509Principal;
               X509Name var55 = var52.getName();
               var54.<init>(var55);
               Iterator var58 = this.certs.iterator();

               while(var58.hasNext()) {
                  X509Certificate var59 = (X509Certificate)var58.next();
                  BigInteger var60 = var59.getSerialNumber();
                  if(var53.equals(var60)) {
                     Principal var63 = var59.getIssuerDN();
                     if(var54.equals(var63)) {
                        this.signCert = var59;
                        break;
                     }
                  }
               }

               if(this.signCert == null) {
                  StringBuilder var67 = (new StringBuilder()).append("Can\'t find signing certificate with serial ");
                  byte var69 = 16;
                  String var70 = var53.toString(var69);
                  String var71 = var67.append(var70).toString();
                  throw new SecurityException(var71);
               } else {
                  String var72 = var50.getDigestAlgorithm().getObjectId().getId();
                  this.digestAlgorithm = var72;
                  byte[] var73 = var50.getEncryptedDigest().getOctets();
                  this.digest = var73;
                  String var74 = var50.getDigestEncryptionAlgorithm().getObjectId().getId();
                  this.digestEncryptionAlgorithm = var74;
                  String var75 = this.getDigestAlgorithm();
                  Signature var77 = Signature.getInstance(var75, var2);
                  this.sig = var77;
                  Signature var78 = this.sig;
                  PublicKey var79 = this.signCert.getPublicKey();
                  var78.initVerify(var79);
               }
            }
  @Override
  public SecurityKeyData processRegistrationResponse(
      RegistrationResponse registrationResponse, long currentTimeInMillis) throws U2FException {
    Log.info(">> processRegistrationResponse");

    String sessionId = registrationResponse.getSessionId();
    String clientDataBase64 = registrationResponse.getClientData();
    String rawRegistrationDataBase64 = registrationResponse.getRegistrationData();

    Log.info(">> rawRegistrationDataBase64: " + rawRegistrationDataBase64);
    EnrollSessionData sessionData = dataStore.getEnrollSessionData(sessionId);

    if (sessionData == null) {
      throw new U2FException("Unknown session_id");
    }

    String appId = sessionData.getAppId();
    String clientData = new String(Base64.decodeBase64(clientDataBase64));
    byte[] rawRegistrationData = Base64.decodeBase64(rawRegistrationDataBase64);
    Log.info("-- Input --");
    Log.info("  sessionId: " + sessionId);
    Log.info("  challenge: " + Hex.encodeHexString(sessionData.getChallenge()));
    Log.info("  accountName: " + sessionData.getAccountName());
    Log.info("  clientData: " + clientData);
    Log.info("  rawRegistrationData: " + Hex.encodeHexString(rawRegistrationData));

    RegisterResponse registerResponse = RawMessageCodec.decodeRegisterResponse(rawRegistrationData);

    byte[] userPublicKey = registerResponse.getUserPublicKey();
    byte[] keyHandle = registerResponse.getKeyHandle();
    X509Certificate attestationCertificate = registerResponse.getAttestationCertificate();
    byte[] signature = registerResponse.getSignature();
    List<Transports> transports = null;
    try {
      transports = U2fAttestation.Parse(attestationCertificate).getTransports();
    } catch (CertificateParsingException e) {
      Log.warning("Could not parse transports extension " + e.getMessage());
    }

    Log.info("-- Parsed rawRegistrationResponse --");
    Log.info("  userPublicKey: " + Hex.encodeHexString(userPublicKey));
    Log.info("  keyHandle: " + Hex.encodeHexString(keyHandle));
    Log.info("  attestationCertificate: " + attestationCertificate.toString());
    Log.info("  transports: " + transports);
    try {
      Log.info(
          "  attestationCertificate bytes: "
              + Hex.encodeHexString(attestationCertificate.getEncoded()));
    } catch (CertificateEncodingException e) {
      throw new U2FException("Cannot encode certificate", e);
    }
    Log.info("  signature: " + Hex.encodeHexString(signature));

    byte[] appIdSha256 = cryto.computeSha256(appId.getBytes());
    byte[] clientDataSha256 = cryto.computeSha256(clientData.getBytes());
    byte[] signedBytes =
        RawMessageCodec.encodeRegistrationSignedBytes(
            appIdSha256, clientDataSha256, keyHandle, userPublicKey);

    Set<X509Certificate> trustedCertificates = dataStore.getTrustedCertificates();
    if (!trustedCertificates.contains(attestationCertificate)) {
      Log.warning("attestion cert is not trusted");
    }

    verifyBrowserData(
        new JsonParser().parse(clientData), "navigator.id.finishEnrollment", sessionData);

    Log.info("Verifying signature of bytes " + Hex.encodeHexString(signedBytes));
    if (!cryto.verifySignature(attestationCertificate, signedBytes, signature)) {
      throw new U2FException("Signature is invalid");
    }

    // The first time we create the SecurityKeyData, we set the counter value to 0.
    // We don't actually know what the counter value of the real device is - but it will
    // be something bigger (or equal) to 0, so subsequent signatures will check out ok.
    SecurityKeyData securityKeyData =
        new SecurityKeyData(
            currentTimeInMillis,
            transports,
            keyHandle,
            userPublicKey,
            attestationCertificate, /* initial counter value */
            0);
    dataStore.addSecurityKeyData(sessionData.getAccountName(), securityKeyData);

    Log.info("<< processRegistrationResponse");
    return securityKeyData;
  }