001package ezvcard.property; 002 003import java.io.IOException; 004import java.io.InputStream; 005import java.nio.file.Path; 006import java.util.List; 007import java.util.Map; 008import java.util.Objects; 009 010import ezvcard.VCard; 011import ezvcard.VCardVersion; 012import ezvcard.ValidationWarning; 013import ezvcard.parameter.KeyType; 014 015/* 016 Copyright (c) 2012-2026, Michael Angstadt 017 All rights reserved. 018 019 Redistribution and use in source and binary forms, with or without 020 modification, are permitted provided that the following conditions are met: 021 022 1. Redistributions of source code must retain the above copyright notice, this 023 list of conditions and the following disclaimer. 024 2. Redistributions in binary form must reproduce the above copyright notice, 025 this list of conditions and the following disclaimer in the documentation 026 and/or other materials provided with the distribution. 027 028 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 029 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 030 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 031 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 032 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 033 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 034 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 035 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 036 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 037 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 038 039 The views and conclusions contained in the software and documentation are those 040 of the authors and should not be interpreted as representing official policies, 041 either expressed or implied, of the FreeBSD Project. 042 */ 043 044/** 045 * <p> 046 * Defines a public encryption key. 047 * </p> 048 * 049 * <p> 050 * <b>Code sample (creating)</b> 051 * </p> 052 * 053 * <pre class="brush:java"> 054 * VCard vcard = new VCard(); 055 * 056 * //URL 057 * Key key = new Key("http://www.mywebsite.com/my-public-key.pgp", KeyType.PGP); 058 * vcard.addKey(key); 059 * 060 * //URI 061 * Key key = new Key("OPENPGP4FPR:ABAF11C65A2970B130ABE3C479BE3E4300411886", null); 062 * vcard.addKey(key); 063 * 064 * //binary data 065 * byte[] data = ... 066 * key = new Key(data, KeyType.PGP); 067 * vcard.addKey(key); 068 * 069 * //plain text value 070 * key = new Key(); 071 * key.setText("...", KeyType.PGP); 072 * vcard.addKey(key); 073 * </pre> 074 * 075 * <p> 076 * <b>Code sample (retrieving)</b> 077 * </p> 078 * 079 * <pre class="brush:java"> 080 * VCard vcard = ... 081 * for (Key key : vcard.getKeys()) { 082 * KeyType contentType = key.getContentType(); //e.g. "application/pgp-keys" 083 * 084 * String url = key.getUrl(); 085 * if (url != null) { 086 * //property value is a URL 087 * continue; 088 * } 089 * 090 * byte[] data = key.getData(); 091 * if (data != null) { 092 * //property value is binary data 093 * continue; 094 * } 095 * 096 * String text = key.getText(); 097 * if (text != null) { 098 * //property value is plain-text 099 * continue; 100 * } 101 * } 102 * </pre> 103 * 104 * <p> 105 * <b>Property name:</b> {@code KEY} 106 * </p> 107 * <p> 108 * <b>Supported versions:</b> {@code 2.1, 3.0, 4.0} 109 * </p> 110 * @author Michael Angstadt 111 * @see <a href="http://tools.ietf.org/html/rfc6350#page-48">RFC 6350 p.48</a> 112 * @see <a href="http://tools.ietf.org/html/rfc2426#page-26">RFC 2426 p.26</a> 113 * @see <a href="http://www.imc.org/pdi/vcard-21.doc">vCard 2.1 p.22</a> 114 */ 115public class Key extends BinaryProperty<KeyType> { 116 private String text; 117 118 /** 119 * Creates an empty key property. 120 */ 121 public Key() { 122 super(); 123 } 124 125 /** 126 * Creates a key property. 127 * @param data the binary data 128 * @param type the type of key (e.g. PGP) 129 */ 130 public Key(byte[] data, KeyType type) { 131 super(data, type); 132 } 133 134 /** 135 * Creates a key property. 136 * @param url the URI or URL to the key 137 * @param type the type of key (e.g. PGP) or null if the type can be 138 * identified from the URI 139 */ 140 public Key(String url, KeyType type) { 141 super(url, type); 142 } 143 144 /** 145 * Creates a key property. 146 * @param in an input stream to the binary data (will be closed) 147 * @param type the content type (e.g. PGP) 148 * @throws IOException if there's a problem reading from the input stream 149 */ 150 public Key(InputStream in, KeyType type) throws IOException { 151 super(in, type); 152 } 153 154 /** 155 * Creates a key property. 156 * @param file the key file 157 * @param type the content type (e.g. PGP) 158 * @throws IOException if there's a problem reading from the file 159 */ 160 public Key(Path file, KeyType type) throws IOException { 161 super(file, type); 162 } 163 164 /** 165 * Copy constructor. 166 * @param original the property to make a copy of 167 */ 168 public Key(Key original) { 169 super(original); 170 text = original.text; 171 } 172 173 /** 174 * Sets a plain text representation of the key. 175 * @param text the key in plain text 176 * @param type the key type 177 */ 178 public void setText(String text, KeyType type) { 179 this.text = text; 180 data = null; 181 url = null; 182 setContentType(type); 183 } 184 185 /** 186 * Gets the plain text representation of the key. 187 * @return the key in plain text 188 */ 189 public String getText() { 190 return text; 191 } 192 193 /** 194 * Sets the URL or URI of the key. 195 * @param url the URL or URI of the key 196 * @param type the type of key (e.g. PGP) or null if the type can be 197 * identified from the URI 198 */ 199 @Override 200 public void setUrl(String url, KeyType type) { 201 super.setUrl(url, type); 202 text = null; 203 } 204 205 /** 206 * Gets the URL or URI of the key. 207 * @return the URL/URI or null if there is none 208 */ 209 @Override 210 public String getUrl() { 211 return super.getUrl(); 212 } 213 214 @Override 215 public void setData(byte[] data, KeyType type) { 216 super.setData(data, type); 217 text = null; 218 } 219 220 @Override 221 protected void _validate(List<ValidationWarning> warnings, VCardVersion version, VCard vcard) { 222 if (url == null && data == null && text == null) { 223 warnings.add(new ValidationWarning(8)); 224 } 225 226 if (url != null && (version == VCardVersion.V2_1 || version == VCardVersion.V3_0)) { 227 warnings.add(new ValidationWarning(15)); 228 } 229 } 230 231 @Override 232 protected Map<String, Object> toStringValues() { 233 Map<String, Object> values = super.toStringValues(); 234 values.put("text", text); 235 return values; 236 } 237 238 @Override 239 public Key copy() { 240 return new Key(this); 241 } 242 243 @Override 244 public int hashCode() { 245 final int prime = 31; 246 int result = super.hashCode(); 247 result = prime * result + Objects.hash(text); 248 return result; 249 } 250 251 @Override 252 public boolean equals(Object obj) { 253 if (this == obj) return true; 254 if (!super.equals(obj)) return false; 255 if (getClass() != obj.getClass()) return false; 256 Key other = (Key) obj; 257 return Objects.equals(text, other.text); 258 } 259}