001/*
002 * jPOS Project [http://jpos.org]
003 * Copyright (C) 2000-2026 jPOS Software SRL
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jpos.emv.cryptogram;
020
021import org.jpos.security.ARPCMethod;
022import org.jpos.security.MKDMethod;
023import org.jpos.security.SKDMethod;
024
025/**
026 * M/Chip Cryptogram Specification 
027 * 
028 * @author Rainer Reyes
029 */
030public class MChipCryptogram implements CryptogramSpec {
031
032    private final CVNMCDataBuilder dataBuilder;
033    private final SKDMethod skdMethod;
034
035
036    /**
037     * Configures the cryptogram spec from the encoded Cryptogram Version Number.
038     *
039     * @param cryptogramVersionNumber two-hex-digit Cryptogram Version Number (CVN)
040     *                                that selects the data builder and SKD method
041     * @throws IllegalArgumentException if the CVN does not encode a supported variant
042     */
043    public MChipCryptogram(String cryptogramVersionNumber) {
044        byte data = (byte) Integer.parseInt(cryptogramVersionNumber, 16);
045        this.dataBuilder = new CVNMCDataBuilder((data & 1) == 1); // byte 1 = 1
046        // byte 3-2
047        if ((data >> 1 & 0x03) == 0x00) { // bits = 00
048            // byte 3-2 = 00
049            skdMethod = SKDMethod.MCHIP;
050        } else if ((data >> 1 & 0x03) == 0x02) { // bits = 10
051            // byte 3-2 = 10
052            skdMethod = SKDMethod.EMV_CSKD;
053        } else {
054            throw new IllegalArgumentException("Cryptogram version not supported");
055        }
056    }
057
058    @Override
059    public MKDMethod getMKDMethod() {
060        return MKDMethod.OPTION_A;
061    }
062
063    @Override
064    public SKDMethod getSKDMethod() {
065        return skdMethod;
066    }
067
068    @Override
069    public ARPCMethod getARPCMethod() {
070        return ARPCMethod.METHOD_1;
071    }
072
073    @Override
074    public CryptogramDataBuilder getDataBuilder() {
075        return dataBuilder;
076    }
077}