001/** 002 * 003 * Copyright 2017 Florian Schmaus 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smackx.eme.element; 018 019import java.util.HashMap; 020import java.util.Map; 021 022import org.jivesoftware.smack.packet.ExtensionElement; 023import org.jivesoftware.smack.packet.Message; 024import org.jivesoftware.smack.util.StringUtils; 025import org.jivesoftware.smack.util.XmlStringBuilder; 026 027public class ExplicitMessageEncryptionElement implements ExtensionElement { 028 029 private static final Map<String, ExplicitMessageEncryptionProtocol> PROTOCOL_LUT = new HashMap<>(); 030 031 public static final String ELEMENT = "encryption"; 032 033 public static final String NAMESPACE = "urn:xmpp:eme:0"; 034 035 public enum ExplicitMessageEncryptionProtocol { 036 037 /** 038 * The encryption method specified in <a href="https://xmpp.org/extensions/xep-0373.html">XEP-0373: OpenPGP for 039 * XMPP</a>. 040 */ 041 openpgpV0("urn:xmpp:openpgp:0", "OpenPGP for XMPP (XEP-0373)"), 042 043 otrV0("urn:xmpp:otr:0", "Off-the-Record Messaging (XEP-0364)"), 044 045 legacyOpenPGP("jabber:x:encrypted", "Legacy OpenPGP for XMPP [DANGEROUS, DO NOT USE!]"), 046 ; 047 048 private final String namespace; 049 private final String name; 050 051 ExplicitMessageEncryptionProtocol(String namespace, String name) { 052 this.namespace = namespace; 053 this.name = name; 054 PROTOCOL_LUT.put(namespace, this); 055 } 056 057 public String getNamespace() { 058 return namespace; 059 } 060 061 public String getName() { 062 return name; 063 } 064 065 public static ExplicitMessageEncryptionProtocol from(String namespace) { 066 return PROTOCOL_LUT.get(namespace); 067 } 068 } 069 070 private final String encryptionNamespace; 071 072 private final String name; 073 074 private boolean isUnknownProtocol; 075 076 private ExplicitMessageEncryptionProtocol protocolCache; 077 078 public ExplicitMessageEncryptionElement(ExplicitMessageEncryptionProtocol protocol) { 079 this(protocol.getNamespace(), protocol.getName()); 080 } 081 082 public ExplicitMessageEncryptionElement(String encryptionNamespace) { 083 this(encryptionNamespace, null); 084 } 085 086 public ExplicitMessageEncryptionElement(String encryptionNamespace, String name) { 087 this.encryptionNamespace = StringUtils.requireNotNullOrEmpty(encryptionNamespace, 088 "encryptionNamespace must not be null"); 089 this.name = name; 090 } 091 092 public ExplicitMessageEncryptionProtocol getProtocol() { 093 if (protocolCache != null) { 094 return protocolCache; 095 } 096 097 if (isUnknownProtocol) { 098 return null; 099 } 100 101 ExplicitMessageEncryptionProtocol protocol = PROTOCOL_LUT.get(encryptionNamespace); 102 if (protocol == null) { 103 isUnknownProtocol = true; 104 return null; 105 } 106 107 protocolCache = protocol; 108 return protocol; 109 } 110 111 public String getEncryptionNamespace() { 112 return encryptionNamespace; 113 } 114 115 /** 116 * Get the optional name of the encryption method. 117 * 118 * @return the name of the encryption method or <code>null</code>. 119 */ 120 public String getName() { 121 return name; 122 } 123 124 @Override 125 public String getElementName() { 126 return ELEMENT; 127 } 128 129 @Override 130 public String getNamespace() { 131 return NAMESPACE; 132 } 133 134 @Override 135 public XmlStringBuilder toXML() { 136 XmlStringBuilder xml = new XmlStringBuilder(this); 137 xml.attribute("namespace", getEncryptionNamespace()); 138 xml.optAttribute("name", getName()); 139 xml.closeEmptyElement(); 140 return xml; 141 } 142 143 public static ExplicitMessageEncryptionElement from(Message message) { 144 return message.getExtension(ELEMENT, NAMESPACE); 145 } 146}