예제 #1
0
 /// <summary>Decrypt the key and iv of the negotiated cipher option.</summary>
 /// <param name="option">negotiated cipher option</param>
 /// <param name="sasl">SASL participant representing client</param>
 /// <returns>
 /// CipherOption negotiated cipher option which contains the
 /// decrypted key and iv
 /// </returns>
 /// <exception cref="System.IO.IOException">for any error</exception>
 public static CipherOption Unwrap(CipherOption option, SaslParticipant sasl)
 {
     if (option != null)
     {
         byte[] inKey = option.GetInKey();
         if (inKey != null)
         {
             inKey = sasl.Unwrap(inKey, 0, inKey.Length);
         }
         byte[] outKey = option.GetOutKey();
         if (outKey != null)
         {
             outKey = sasl.Unwrap(outKey, 0, outKey.Length);
         }
         return(new CipherOption(option.GetCipherSuite(), inKey, option.GetInIv(), outKey,
                                 option.GetOutIv()));
     }
     return(null);
 }
예제 #2
0
        /// <summary>
        /// Create IOStreamPair of
        /// <see cref="Org.Apache.Hadoop.Crypto.CryptoInputStream"/>
        /// and
        /// <see cref="Org.Apache.Hadoop.Crypto.CryptoOutputStream"/>
        /// </summary>
        /// <param name="conf">the configuration</param>
        /// <param name="cipherOption">negotiated cipher option</param>
        /// <param name="out">underlying output stream</param>
        /// <param name="in">underlying input stream</param>
        /// <param name="isServer">is server side</param>
        /// <returns>IOStreamPair the stream pair</returns>
        /// <exception cref="System.IO.IOException">for any error</exception>
        public static IOStreamPair CreateStreamPair(Configuration conf, CipherOption cipherOption
                                                    , OutputStream @out, InputStream @in, bool isServer)
        {
            if (Log.IsDebugEnabled())
            {
                Log.Debug("Creating IOStreamPair of CryptoInputStream and " + "CryptoOutputStream."
                          );
            }
            CryptoCodec codec = CryptoCodec.GetInstance(conf, cipherOption.GetCipherSuite());

            byte[]      inKey  = cipherOption.GetInKey();
            byte[]      inIv   = cipherOption.GetInIv();
            byte[]      outKey = cipherOption.GetOutKey();
            byte[]      outIv  = cipherOption.GetOutIv();
            InputStream cIn    = new CryptoInputStream(@in, codec, isServer ? inKey : outKey, isServer
                                 ? inIv : outIv);
            OutputStream cOut = new CryptoOutputStream(@out, codec, isServer ? outKey : inKey
                                                       , isServer ? outIv : inIv);

            return(new IOStreamPair(cIn, cOut));
        }
예제 #3
0
        /// <summary>This method actually executes the server-side SASL handshake.</summary>
        /// <param name="underlyingOut">connection output stream</param>
        /// <param name="underlyingIn">connection input stream</param>
        /// <param name="saslProps">properties of SASL negotiation</param>
        /// <param name="callbackHandler">for responding to SASL callbacks</param>
        /// <returns>new pair of streams, wrapped after SASL negotiation</returns>
        /// <exception cref="System.IO.IOException">for any error</exception>
        private IOStreamPair DoSaslHandshake(OutputStream underlyingOut, InputStream underlyingIn
                                             , IDictionary <string, string> saslProps, CallbackHandler callbackHandler)
        {
            DataInputStream  @in  = new DataInputStream(underlyingIn);
            DataOutputStream @out = new DataOutputStream(underlyingOut);
            SaslParticipant  sasl = SaslParticipant.CreateServerSaslParticipant(saslProps, callbackHandler
                                                                                );
            int magicNumber = @in.ReadInt();

            if (magicNumber != SaslTransferMagicNumber)
            {
                throw new InvalidMagicNumberException(magicNumber, dnConf.GetEncryptDataTransfer(
                                                          ));
            }
            try
            {
                // step 1
                byte[] remoteResponse = DataTransferSaslUtil.ReadSaslMessage(@in);
                byte[] localResponse  = sasl.EvaluateChallengeOrResponse(remoteResponse);
                DataTransferSaslUtil.SendSaslMessage(@out, localResponse);
                // step 2 (server-side only)
                IList <CipherOption> cipherOptions = Lists.NewArrayList();
                remoteResponse = DataTransferSaslUtil.ReadSaslMessageAndNegotiationCipherOptions(
                    @in, cipherOptions);
                localResponse = sasl.EvaluateChallengeOrResponse(remoteResponse);
                // SASL handshake is complete
                DataTransferSaslUtil.CheckSaslComplete(sasl, saslProps);
                CipherOption cipherOption = null;
                if (sasl.IsNegotiatedQopPrivacy())
                {
                    // Negotiate a cipher option
                    cipherOption = DataTransferSaslUtil.NegotiateCipherOption(dnConf.GetConf(), cipherOptions
                                                                              );
                    if (cipherOption != null)
                    {
                        if (Log.IsDebugEnabled())
                        {
                            Log.Debug("Server using cipher suite " + cipherOption.GetCipherSuite().GetName());
                        }
                    }
                }
                // If negotiated cipher option is not null, wrap it before sending.
                DataTransferSaslUtil.SendSaslMessageAndNegotiatedCipherOption(@out, localResponse
                                                                              , DataTransferSaslUtil.Wrap(cipherOption, sasl));
                // If negotiated cipher option is not null, we will use it to create
                // stream pair.
                return(cipherOption != null?DataTransferSaslUtil.CreateStreamPair(dnConf.GetConf
                                                                                      (), cipherOption, underlyingOut, underlyingIn, true) : sasl.CreateStreamPair(@out
                                                                                                                                                                   , @in));
            }
            catch (IOException ioe)
            {
                if (ioe is SaslException && ioe.InnerException != null && ioe.InnerException is InvalidEncryptionKeyException)
                {
                    // This could just be because the client is long-lived and hasn't gotten
                    // a new encryption key from the NN in a while. Upon receiving this
                    // error, the client will get a new encryption key from the NN and retry
                    // connecting to this DN.
                    SendInvalidKeySaslErrorMessage(@out, ioe.InnerException.Message);
                }
                else
                {
                    DataTransferSaslUtil.SendGenericSaslErrorMessage(@out, ioe.Message);
                }
                throw;
            }
        }