All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jmrtd.protocol.PACEResult Maven / Gradle / Ivy

There is a newer version: 0.7.42
Show newest version
/*
 * JMRTD - A Java API for accessing machine readable travel documents.
 *
 * Copyright (C) 2006 - 2017  The JMRTD team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 * $Id: PACEResult.java 1698 2017-09-04 12:41:58Z martijno $
 */

package org.jmrtd.protocol;

import java.io.Serializable;
import java.security.KeyPair;
import java.security.PublicKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECPoint;
import java.util.Arrays;

import org.jmrtd.lds.PACEInfo.MappingType;

/**
 * Result of PACE protocol.
 * 
 * @author The JMRTD team ([email protected])
 *
 * @version $Revision: 1698 $
 */
public class PACEResult implements Serializable {

  private static final long serialVersionUID = -6819675856205885052L;

  private MappingType mappingType;
  private String agreementAlg;
  private String cipherAlg;
  private String digestAlg;
  private int keyLength;

  private PACEMappingResult mappingResult;

  private PublicKey piccPublicKey;

  private KeyPair pcdKeyPair;

  private SecureMessagingWrapper wrapper;

  /**
   * The result of a PACE protocol run.
   * 
   * @param mappingType the mapping type, {@code GM}, {@code IM}, or {@code CAM}
   * @param agreementAlg the agreement algorithm, {@code "DH"} or {@code "ECDH"}
   * @param cipherAlg the cipher algorithm
   * @param digestAlg the digest algorithm
   * @param keyLength the key length
   * @param mappingResult the result of the mapping step
   * @param pcdKeyPair the key pair generated by the PCD
   * @param piccPublicKey the public key sent by the PICC
   * @param wrapper the resulting secure messaging wrapper
   */
  public PACEResult(MappingType mappingType, String agreementAlg, String cipherAlg, String digestAlg, int keyLength,
      PACEMappingResult mappingResult,
      KeyPair pcdKeyPair, PublicKey piccPublicKey, SecureMessagingWrapper wrapper) {
    this.mappingType = mappingType;
    this.agreementAlg = agreementAlg;
    this.cipherAlg = cipherAlg;
    this.digestAlg = digestAlg;
    this.keyLength = keyLength;
    this.mappingResult = mappingResult;
    this.pcdKeyPair = pcdKeyPair;
    this.piccPublicKey = piccPublicKey;
    this.wrapper = wrapper;
  }

  public PACEMappingResult getMappingResult() {
    return mappingResult;
  }

  public SecureMessagingWrapper getWrapper() {
    return wrapper;
  }

  public MappingType getMappingType() {
    return mappingType;
  }

  public String getAgreementAlg() {
    return agreementAlg;
  }

  public String getCipherAlg() {
    return cipherAlg;
  }

  public String getDigestAlg() {
    return digestAlg;
  }

  public void setDigestAlg(String digestAlg) {
    this.digestAlg = digestAlg;
  }

  public int getKeyLength() {
    return keyLength;
  }

  public KeyPair getPCDKeyPair() {
    return pcdKeyPair;
  }

  public PublicKey getPICCPublicKey() {
    return piccPublicKey;
  }

  @Override
  public String toString() {
    return (new StringBuilder())
        .append("PACEResult [mappingType: ").append(mappingType)
        .append(", agreementAlg: " + agreementAlg)
        .append(", cipherAlg: " + cipherAlg)
        .append(", digestAlg: " + digestAlg)
        .append(", keyLength: " + keyLength)
        .append(", mappingResult: " + mappingResult)
        .append(", pcdKeyPair: " + pcdKeyPair)
        .append(", piccPublicKey: " + piccPublicKey)
        .toString();    
  }

  @Override
  public int hashCode() {
    final int prime = 1991;
    int result = 11;
    result = prime * result + ((agreementAlg == null) ? 0 : agreementAlg.hashCode());
    result = prime * result + ((cipherAlg == null) ? 0 : cipherAlg.hashCode());
    result = prime * result + ((digestAlg == null) ? 0 : digestAlg.hashCode());
    result = prime * result + ((mappingResult == null) ? 0 : mappingResult.hashCode());
    result = prime * result + keyLength;
    result = prime * result + ((mappingType == null) ? 0 : mappingType.hashCode());
    result = prime * result + ((pcdKeyPair == null) ? 0 : pcdKeyPair.hashCode());
    result = prime * result + ((piccPublicKey == null) ? 0 : piccPublicKey.hashCode());
    result = prime * result + ((wrapper == null) ? 0 : wrapper.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }

    PACEResult other = (PACEResult)obj;
    if (agreementAlg == null) {
      if (other.agreementAlg != null) {
        return false;
      }
    } else if (!agreementAlg.equals(other.agreementAlg)) {
      return false;
    }
    if (cipherAlg == null) {
      if (other.cipherAlg != null) {
        return false;
      }
    } else if (!cipherAlg.equals(other.cipherAlg)) {
      return false;
    }
    if (digestAlg == null) {
      if (other.digestAlg != null) {
        return false;
      }
    } else if (!digestAlg.equals(other.digestAlg)) {
      return false;
    }
    if (mappingResult == null) {
      if (other.mappingResult != null) {
        return false;
      }
    } else if (!mappingResult.equals(other.mappingResult)) {
      return false;
    }
    if (keyLength != other.keyLength) {
      return false;
    }
    if (mappingType != other.mappingType) {
      return false;
    }
    if (pcdKeyPair == null) {
      if (other.pcdKeyPair != null) {
        return false;
      }
    } else if (!pcdKeyPair.equals(other.pcdKeyPair)) {
      return false;
    }
    if (piccPublicKey == null) {
      if (other.piccPublicKey != null) {
        return false;
      }
    } else if (!piccPublicKey.equals(other.piccPublicKey)) {
      return false;
    }
    if (wrapper == null) {
      if (other.wrapper != null) {
        return false;
      }
    } else if (!wrapper.equals(other.wrapper)) {
      return false;
    }

    return true;
  }

  public static abstract class PACEMappingResult {

    private AlgorithmParameterSpec staticParameters;

    private AlgorithmParameterSpec ephemeralParameters;

    private byte[] piccNonce;

    public PACEMappingResult(AlgorithmParameterSpec staticParameters, byte[] piccNonce, AlgorithmParameterSpec ephemeralParameters) {
      this.staticParameters = staticParameters;
      this.ephemeralParameters = ephemeralParameters;

      this.piccNonce = null;
      if (piccNonce != null) {
        this.piccNonce = new byte[piccNonce.length];
        System.arraycopy(piccNonce, 0, this.piccNonce, 0, piccNonce.length);
      }
    }

    public AlgorithmParameterSpec getStaticParameters() {
      return staticParameters;
    }

    public AlgorithmParameterSpec getEphemeralParameters() {
      return ephemeralParameters;
    }

    public byte[] getPICCNonce() {
      return piccNonce;
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + ((ephemeralParameters == null) ? 0 : ephemeralParameters.hashCode());
      result = prime * result + Arrays.hashCode(piccNonce);
      result = prime * result + ((staticParameters == null) ? 0 : staticParameters.hashCode());
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (obj == null) {
        return false;
      }
      if (getClass() != obj.getClass()) {
        return false;
      }

      PACEMappingResult other = (PACEMappingResult) obj;
      if (ephemeralParameters == null) {
        if (other.ephemeralParameters != null) {
          return false;
        }
      } else if (!ephemeralParameters.equals(other.ephemeralParameters)) {
        return false;
      }
      if (!Arrays.equals(piccNonce, other.piccNonce)) {
        return false;
      }
      if (staticParameters == null) {
        if (other.staticParameters != null) {
          return false;
        }
      } else if (!staticParameters.equals(other.staticParameters)) {
        return false;
      }

      return true;
    }
  }

  public static abstract class PACEGMMappingResult extends PACEMappingResult {

    private PublicKey piccMappingPublicKey;
    private KeyPair pcdMappingKeyPair;

    public PACEGMMappingResult(AlgorithmParameterSpec staticParameters, byte[] piccNonce,
        PublicKey piccMappingPublicKey, KeyPair pcdMappingKeyPair,
        AlgorithmParameterSpec ephemeralParameters) {
      super(staticParameters, piccNonce, ephemeralParameters);
      this.piccMappingPublicKey = piccMappingPublicKey;
      this.pcdMappingKeyPair = pcdMappingKeyPair;
    }

    public PublicKey getPICCMappingPublicKey() {
      return piccMappingPublicKey;
    }

    public KeyPair getPCDMappingKeyPair() {
      return pcdMappingKeyPair;
    }
    
    @Override
    public int hashCode() {
      final int prime = 31;
      int result = super.hashCode();
      result = prime * result + ((piccMappingPublicKey == null) ? 0 : piccMappingPublicKey.hashCode());
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (!super.equals(obj)) {
        return false;
      }
      if (getClass() != obj.getClass()) {
        return false;
      }

      PACEGMMappingResult other = (PACEGMMappingResult) obj;
      if (piccMappingPublicKey == null) {
        if (other.piccMappingPublicKey != null) {
          return false;
        }
      } else if (!piccMappingPublicKey.equals(other.piccMappingPublicKey)) {
        return false;
      }

      if (pcdMappingKeyPair == null) {
        if (other.pcdMappingKeyPair != null) {
          return false;
        }
      } else if (!pcdMappingKeyPair.equals(other.pcdMappingKeyPair)) {
        return false;
      }
      
      return true;
    }
  }

  public static class PACEGMWithECDHMappingResult extends PACEGMMappingResult {

    private ECPoint sharedSecretPoint;

    public PACEGMWithECDHMappingResult(AlgorithmParameterSpec staticParameters,
        byte[] piccNonce, PublicKey piccMappingPublicKey, KeyPair pcdMappingKeyPair, ECPoint sharedSecretPoint,
        AlgorithmParameterSpec ephemeralParameters) {
      super(staticParameters, piccNonce, piccMappingPublicKey, pcdMappingKeyPair, ephemeralParameters);
      this.sharedSecretPoint = sharedSecretPoint;
    }

    public ECPoint getSharedSecretPoint() {
      return sharedSecretPoint;
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = super.hashCode();
      result = prime * result + ((sharedSecretPoint == null) ? 0 : sharedSecretPoint.hashCode());
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (!super.equals(obj)) {
        return false;
      }
      if (getClass() != obj.getClass()) {
        return false;
      }

      PACEGMWithECDHMappingResult other = (PACEGMWithECDHMappingResult) obj;
      if (sharedSecretPoint == null) {
        if (other.sharedSecretPoint != null) {
          return false;
        }
      } else if (!sharedSecretPoint.equals(other.sharedSecretPoint)) {
        return false;
      }

      return true;
    }
  }

  public static class PACEGMWithDHMappingResult extends PACEGMMappingResult {

    private byte[] sharedSecret;

    public PACEGMWithDHMappingResult(AlgorithmParameterSpec staticParameters, byte[] piccNonce,
        PublicKey piccMappingPublicKey, KeyPair pcdMappingKeyPair,
        byte[] sharedSecret, AlgorithmParameterSpec ephemeralParameters) {
      super(staticParameters, piccNonce, piccMappingPublicKey, pcdMappingKeyPair, ephemeralParameters);
      this.sharedSecret = null;
      if (sharedSecret != null) {
        this.sharedSecret = new byte[sharedSecret.length];
        System.arraycopy(sharedSecret, 0, this.sharedSecret, 0, sharedSecret.length);
      }
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = super.hashCode();
      result = prime * result + Arrays.hashCode(sharedSecret);
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (!super.equals(obj)) {
        return false;
      }
      if (getClass() != obj.getClass()) {
        return false;
      }

      PACEGMWithDHMappingResult other = (PACEGMWithDHMappingResult) obj;
      if (!Arrays.equals(sharedSecret, other.sharedSecret)) {
        return false;
      }

      return true;
    }
  }

  public static class PACEIMMappingResult extends PACEMappingResult {

    private byte[] pcdNonce;

    public PACEIMMappingResult(AlgorithmParameterSpec staticParameters, byte[] piccNonce, byte[] pcdNonce, AlgorithmParameterSpec ephemeralParameters) {
      super(staticParameters, piccNonce, ephemeralParameters);

      this.pcdNonce = null;
      if (pcdNonce != null) {
        this.pcdNonce = new byte[pcdNonce.length];
        System.arraycopy(pcdNonce, 0 , this.pcdNonce, 0, pcdNonce.length);
      }
    }

    public byte[] getPCDNonce() {
      return pcdNonce; // FIXME
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = super.hashCode();
      result = prime * result + Arrays.hashCode(pcdNonce);
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (!super.equals(obj)) {
        return false;
      }
      if (getClass() != obj.getClass()) {
        return false;
      }
      
      PACEIMMappingResult other = (PACEIMMappingResult) obj;
      if (!Arrays.equals(pcdNonce, other.pcdNonce)) {
        return false;
      }
      
      return true;
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy