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.q2.cli.ssm.actions;
020
021import org.jpos.q2.CLIContext;
022import org.jpos.q2.cli.ssm.SsmActionBase;
023import org.jpos.security.SMException;
024import org.jpos.security.jceadapter.JCESecurityModule;
025
026/**
027 * Form a key from clear components.
028 *
029 * @author Alwyn Schoeman - alwyn.schoeman@gmail.com
030 */
031public class FK extends SsmActionBase {
032    private boolean prompt = false;
033
034    @Override
035    protected boolean checkUsage(CLIContext cli, String[] strings) {
036        // This doesn't cover all combinations, but it is assumed the operation will fail elsewhere.
037        if (strings.length == 4) {
038            if (!strings[3].equals("-prompt")) {
039                cli.println("Usage: FK KeyLength keyType -prompt");
040                cli.println("Usage: FK KeyLength keyType component1 component2 component3");
041                return false;
042            } else {
043                prompt = true;
044                return true;
045            }
046        }
047        if (strings.length < 6) {
048            cli.println("Usage: FK KeyLength keyType -prompt");
049            cli.println("Usage: FK KeyLength keyType component1 component2 component3");
050            return false;
051        }
052
053        return true;
054    }
055
056    @Override
057    protected void doCommand(
058            CLIContext cli,
059            JCESecurityModule sm,
060            short keyLength,
061            String[] strings)
062            throws SMException {
063        if (prompt) {
064            String key1 = readKeyComponent(cli, 1);
065            String key2 = readKeyComponent(cli, 2);
066            String key3 = readKeyComponent(cli, 3);
067            sm.formKEYfromThreeClearComponents(
068                    keyLength, strings[2].toUpperCase(), key1, key2, key3);
069        } else {
070            sm.formKEYfromThreeClearComponents(
071                    keyLength, strings[2].toUpperCase(), strings[3], strings[4], strings[5]);
072        }
073    }
074
075    private String readKeyComponent(CLIContext cli, int kcNumber) {
076        boolean validComponent = false;
077        String key = null;
078        cli.println("Key component " + kcNumber + ":");
079        while (!validComponent) {
080            while (true) {
081                key = cli.readSecurely("Please enter key component:");
082                if (key != null && key.length() == 32) break;
083                cli.println("Key component must be 32 hexadecimal characters.");
084            }
085            String second;
086            while (true) {
087                second = cli.readSecurely("Please re-enter key component:");
088                if (second != null && second.length() == 32) break;
089                cli.println("Key component must be 32 hexadecimal characters.");
090            }
091            validComponent = key.equals(second);
092            if (!validComponent) {
093                cli.println("Entered key components don't match.");
094            }
095        }
096        return key;
097    }
098}