예제 #1
0
  public int getCipherTextBlockSize(X509Certificate certificate, SecurityPolicy securityPolicy) {
    SecurityAlgorithm algorithm = securityPolicy.getAsymmetricEncryptionAlgorithm();

    switch (algorithm) {
      case Rsa15:
      case RsaOaep:
        return (getAsymmetricKeyLength(certificate) + 1) / 8;
    }

    return 1;
  }
예제 #2
0
  public Cipher getAndInitializeCipher(
      X509Certificate serverCertificate, SecurityPolicy securityPolicy) throws UaException {

    assert (serverCertificate != null);

    try {
      String transformation = securityPolicy.getAsymmetricEncryptionAlgorithm().getTransformation();
      Cipher cipher = Cipher.getInstance(transformation);
      cipher.init(Cipher.ENCRYPT_MODE, serverCertificate.getPublicKey());
      return cipher;
    } catch (GeneralSecurityException e) {
      throw new UaException(StatusCodes.Bad_SecurityChecksFailed, e);
    }
  }
예제 #3
0
  @Override
  public Tuple2<UserIdentityToken, SignatureData> getIdentityToken(
      EndpointDescription endpoint, ByteString serverNonce) throws Exception {

    UserTokenPolicy tokenPolicy =
        Arrays.stream(endpoint.getUserIdentityTokens())
            .filter(t -> t.getTokenType() == UserTokenType.UserName)
            .findFirst()
            .orElseThrow(() -> new Exception("no username token policy found"));

    String policyId = tokenPolicy.getPolicyId();

    SecurityPolicy securityPolicy = SecurityPolicy.None;

    String securityPolicyUri = tokenPolicy.getSecurityPolicyUri();
    try {
      if (securityPolicyUri != null && !securityPolicyUri.isEmpty()) {
        securityPolicy = SecurityPolicy.fromUri(securityPolicyUri);
      } else {
        securityPolicyUri = endpoint.getSecurityPolicyUri();
        securityPolicy = SecurityPolicy.fromUri(securityPolicyUri);
      }
    } catch (Throwable t) {
      logger.warn(
          "Error parsing SecurityPolicy for uri={}, falling back to no security.",
          securityPolicyUri);
    }

    byte[] passwordBytes = password.getBytes("UTF-8");
    byte[] nonceBytes = Optional.ofNullable(serverNonce.bytes()).orElse(new byte[0]);

    ByteBuf buffer = Unpooled.buffer().order(ByteOrder.LITTLE_ENDIAN);

    if (securityPolicy == SecurityPolicy.None) {
      buffer.writeBytes(passwordBytes);
    } else {
      buffer.writeInt(passwordBytes.length + nonceBytes.length);
      buffer.writeBytes(passwordBytes);
      buffer.writeBytes(nonceBytes);

      ByteString bs = endpoint.getServerCertificate();
      X509Certificate certificate = CertificateUtil.decodeCertificate(bs.bytes());

      int plainTextBlockSize = getPlainTextBlockSize(certificate, securityPolicy);
      int cipherTextBlockSize = getCipherTextBlockSize(certificate, securityPolicy);
      int blockCount = (buffer.readableBytes() + plainTextBlockSize - 1) / plainTextBlockSize;
      Cipher cipher = getAndInitializeCipher(certificate, securityPolicy);

      ByteBuffer plainTextNioBuffer = buffer.nioBuffer();
      ByteBuffer cipherTextNioBuffer =
          Unpooled.buffer(cipherTextBlockSize * blockCount)
              .order(ByteOrder.LITTLE_ENDIAN)
              .nioBuffer(0, cipherTextBlockSize * blockCount);

      for (int blockNumber = 0; blockNumber < blockCount; blockNumber++) {
        int position = blockNumber * plainTextBlockSize;
        int limit = Math.min(buffer.readableBytes(), (blockNumber + 1) * plainTextBlockSize);
        plainTextNioBuffer.position(position).limit(limit);

        cipher.doFinal(plainTextNioBuffer, cipherTextNioBuffer);
      }

      cipherTextNioBuffer.flip();
      buffer = Unpooled.wrappedBuffer(cipherTextNioBuffer);
    }

    byte[] bs = new byte[buffer.readableBytes()];
    buffer.readBytes(bs);

    // UA Part 4, Section 7.35.3 UserNameIdentityToken:
    // encryptionAlgorithm parameter is null if the password is not encrypted.
    String securityAlgorithmUri = securityPolicy.getAsymmetricEncryptionAlgorithm().getUri();
    String encryptionAlgorithm = securityAlgorithmUri.isEmpty() ? null : securityAlgorithmUri;

    UserNameIdentityToken token =
        new UserNameIdentityToken(policyId, username, ByteString.of(bs), encryptionAlgorithm);

    return new Tuple2<>(token, new SignatureData());
  }