001// SPDX-FileCopyrightText: 2018 Paul Schaub <vanitasvitae@fsfe.org> 002// 003// SPDX-License-Identifier: Apache-2.0 004 005package org.pgpainless.algorithm; 006 007import java.util.ArrayList; 008import java.util.List; 009 010import org.bouncycastle.bcpg.sig.KeyFlags; 011 012/** 013 * Enumeration of different key flags. 014 * Key flags denote different capabilities of a key pair. 015 * 016 * @see <a href="https://tools.ietf.org/html/rfc4880#section-5.2.3.21">RFC4880: Key Flags</a> 017 */ 018public enum KeyFlag { 019 020 /** 021 * This key may be used to certify other keys. 022 */ 023 CERTIFY_OTHER (KeyFlags.CERTIFY_OTHER), 024 025 /** 026 * This key may be used to sign data. 027 */ 028 SIGN_DATA (KeyFlags.SIGN_DATA), 029 030 /** 031 * This key may be used to encrypt communications. 032 */ 033 ENCRYPT_COMMS (KeyFlags.ENCRYPT_COMMS), 034 035 /** 036 * This key may be used to encrypt storage. 037 */ 038 ENCRYPT_STORAGE(KeyFlags.ENCRYPT_STORAGE), 039 040 /** 041 * The private component of this key may have been split by a secret-sharing mechanism. 042 */ 043 SPLIT (KeyFlags.SPLIT), 044 045 /** 046 * This key may be used for authentication. 047 */ 048 AUTHENTICATION (KeyFlags.AUTHENTICATION), 049 050 /** 051 * The private component of this key may be in the possession of more than one person. 052 */ 053 SHARED (KeyFlags.SHARED), 054 ; 055 056 private final int flag; 057 058 KeyFlag(int flag) { 059 this.flag = flag; 060 } 061 062 /** 063 * Return the numeric id of the {@link KeyFlag}. 064 * 065 * @return numeric id 066 */ 067 public int getFlag() { 068 return flag; 069 } 070 071 /** 072 * Convert a bitmask into a list of {@link KeyFlag KeyFlags}. 073 * 074 * @param bitmask bitmask 075 * @return list of key flags encoded by the bitmask 076 */ 077 public static List<KeyFlag> fromBitmask(int bitmask) { 078 List<KeyFlag> flags = new ArrayList<>(); 079 for (KeyFlag f : KeyFlag.values()) { 080 if ((bitmask & f.flag) != 0) { 081 flags.add(f); 082 } 083 } 084 return flags; 085 } 086 087 /** 088 * Encode a list of {@link KeyFlag KeyFlags} into a bitmask. 089 * 090 * @param flags list of flags 091 * @return bitmask 092 */ 093 public static int toBitmask(KeyFlag... flags) { 094 int mask = 0; 095 for (KeyFlag f : flags) { 096 mask |= f.getFlag(); 097 } 098 return mask; 099 } 100 101 /** 102 * Return true if the provided bitmask has the bit for the provided flag set. 103 * Return false if the mask does not contain the flag. 104 * 105 * @param mask bitmask 106 * @param flag flag to be tested for 107 * @return true if flag is set, false otherwise 108 */ 109 public static boolean hasKeyFlag(int mask, KeyFlag flag) { 110 return (mask & flag.getFlag()) == flag.getFlag(); 111 } 112 113 public static boolean containsAny(int mask, KeyFlag... flags) { 114 for (KeyFlag flag : flags) { 115 if (hasKeyFlag(mask, flag)) { 116 return true; 117 } 118 } 119 return false; 120 } 121}